Я создал пример кода, используя демонстрационную базу данных Microsoft SQL Server Northwind. Если у вас нет доступа к этой демонстрационной базе данных, вот простой (MS-SQL) скрипт для создания таблицы и строки данных для этого вопроса.
CREATE TABLE [dbo].[Products](
[ProductID] [int] IDENTITY(1,1) NOT NULL,
[ProductName] [nvarchar](40) NOT NULL,
[SupplierID] [int] NULL,
[CategoryID] [int] NULL,
[QuantityPerUnit] [nvarchar](20) NULL,
[UnitPrice] [money] NULL CONSTRAINT [DF_Products_UnitPrice] DEFAULT (0),
[UnitsInStock] [smallint] NULL CONSTRAINT [DF_Products_UnitsInStock] DEFAULT (0),
[UnitsOnOrder] [smallint] NULL CONSTRAINT [DF_Products_UnitsOnOrder] DEFAULT (0),
[ReorderLevel] [smallint] NULL CONSTRAINT [DF_Products_ReorderLevel] DEFAULT (0),
[Discontinued] [bit] NOT NULL CONSTRAINT [DF_Products_Discontinued] DEFAULT (0),
CONSTRAINT [PK_Products] PRIMARY KEY CLUSTERED
(
[ProductID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[Products] ON
GO
INSERT [dbo].[Products] ([ProductID], [ProductName], [SupplierID], [CategoryID], [QuantityPerUnit], [UnitPrice], [UnitsInStock], [UnitsOnOrder], [ReorderLevel], [Discontinued]) VALUES (1, N'Chai', 1, 1, N'10 boxes x 20 bags', 18.0000, 39, 0, 10, 0)
GO
SET IDENTITY_INSERT [dbo].[Products] OFF
GO
Вот код ColdFusion:
<cfset variables.useTempVar = false>
<cfquery datasource="Northwind2014" name="qryNWProducts">
SELECT TOP 1 * from Products;
</cfquery>
<cfdump var="#qryNWProducts#" label="qryNWProducts">
<cfset variables['stProduct'] = {}>
<cfloop index="vcColName" list="#qryNWProducts.columnlist#">
<cfif variables.useTempVar>
<cfset variables['temp'] = qryNWProducts[vcColName]>
<cfset variables['stProduct'][vcColName] = variables.temp>
<cfelse>
<cfset variables['stProduct'][vcColName] = qryNWProducts[vcColName]>
</cfif>
</cfloop>
<cfdump var="#variables['stProduct']#" label="variables['stProduct']">
<cfloop collection="#variables['stProduct']#" item="key"><cfoutput>
variables['stProduct']['#key#'] JVM datatype = #getMetadata(variables['stProduct'][key]).getName()#<br>
</cfoutput></cfloop>
<br>
This always works:<br>
<cfset variables['aPhrase'] = "I ordered " & variables.stProduct.ProductName & " for " & DollarFormat(variables.stProduct.UnitPrice) & ".">
<cfoutput>#variables['aPhrase']#<br></cfoutput>
<br>
With "variables.useTempVar = false", the next line will throw a "Complex object types cannot be converted to simple values. " error.<br>
<cfset variables['aPhrase'] = "I ordered " & variables['stProduct']['ProductName'] & " for " & DollarFormat(variables['stProduct']['UnitPrice']) & ".">
<cfoutput>#variables['aPhrase']#<br></cfoutput>
В приведенном выше коде есть логическая переменная с именем variable.useTempVar вверху, которую можно перевернуть, чтобы увидеть ошибку, которую я получаю.
Похоже, что прямое присвоение (когда переменные.useTempVar = false) из запроса к структуре приводит к тому, что значения структуры имеют тип JVM coldfusion.sql.QueryColumn.
Еще одно примечание: если эта строка кода:
<cfset variables['stProduct'][vcColName] = variables.temp>
изменяется на:
<cfset variables['stProduct'][vcColName] = variables['temp']>
Тип данных JVM будет coldfusion.sql.QueryColumn.
Когда временная переменная с точечной нотацией используется для назначения поля запроса (когда variable.useTempVar = true); типы данных JVM — это простые типы, которые довольно хорошо совпадают с типами столбцов базы данных (java.lang.Integer, java.math.BigDecimal, java.lang.String и т. д.).
Я также экспериментировал с такими утверждениями, и это дало некоторые странные результаты:
<cfset variables['stProduct'][vcColName] = qryNWProducts[vcColName].toString()>
Вот вопрос. Это лучший способ передать простые значения из запроса в структуру? Кажется странным, что для этой работы приходится использовать временную переменную и запись через точку.
Комментарий: я всегда думал, что точечная запись и запись ассоциативного массива эквивалентны. Этот пример кода, кажется, противоречит этому мнению.
qryNWProducts[vcColName]
. При использовании нотации ассоциативного массива с объектами запроса необходимо указать номер строки запроса. В противном случае вы захватываете не тот объект: объект столбца, а не отдельное значение внутри этого столбца. Вместо этого используйтеqryNWProducts[vcColName][1]
, где1
— любой допустимый номер строки в запросе. Предполагая, что вам действительно нужна структура, прежде чем изобретать велосипед, проверили ли вы сайт cflib.org? cflib.org/udf/QueryRowToStruct - person Leigh   schedule 17.06.2015