Могу ли я получить строку запроса по индексу в ColdFusion?

Я хочу получить определенную строку в объекте запроса ColdFusion, не зацикливаясь на ней.

Я хотел бы сделать что-то вроде этого:

<cfquery name="QueryName" datasource="ds">
SELECT *
FROM    tablename
</cfquery>

<cfset x = QueryName[5]>

Но это дает мне сообщение об ошибке, говорящее, что запрос не индексируется на «5». Я точно знаю, что в этом запросе более 5 записей.


person Brian Bolton    schedule 31.07.2009    source источник
comment
CFLib.org снова приходит на помощь: cflib.org/udf/queryGetRow . Это позволит вам сделать <cfset x = queryGetRow(QueryName,5)>   -  person ale    schedule 28.01.2012


Ответы (8)


Вы не можете получить строку в CF ‹= 10. Вы должны получить определенный столбец.

<cfset x = QueryName.columnName[5]>

Однако прошло 8 лет с тех пор, как я опубликовал этот ответ. Судя по всему, CF11 наконец-то реализовал эту функцию. См. ответ FrankieZ.

person Patrick McElhaney    schedule 31.07.2009
comment
Спасибо, это то, что я искал. - person Brian Bolton; 31.07.2009
comment
Я предпочитаю использовать скобки как для строк, так и для столбцов, но любой способ одинаково действителен. ИмяЗапроса[имястолбца][5]. Вам понадобится запись в квадратных скобках, если вы хотите использовать переменную для имени столбца, например. - person ale; 31.07.2009
comment
Не правда. Вы можете получить строку, просто не используя стандартные API CF. И вы не сможете получить доступ к столбцам напрямую по именам переменных — вам нужно знать индекс. Вы можете выполнить myquery.getRow(0), чтобы получить первый coldfusion.sql.imq.Row, и myrow.getColumn(0), чтобы получить первый столбец. У Row также есть метод для получения Object[], представляющего всю строку. - person Mark; 22.03.2011
comment
@Mark: Да, я думаю, что в большинстве случаев это бесполезно для большинства людей. Это Java-объекты/методы, которые не так удобны для повседневного использования: q=myQuery; r=q.getRow(3); rd=x.getRowData(); или просто rd=myQuery.getRow(3).getRowData(); Но это вернет массив java-значений (для которых вам придется разобрать нули/пустые значения), и вы потеряете заголовки ваших столбцов. Я вижу случайную потребность в этом, но обычно добавляет больше сложности, чем вы хотите. - person williambq; 11.06.2013


Я думаю, что есть более простое решение... Я предполагаю, что вы знаете имена своих столбцов и хотите только этот столбец или тот. Тогда вам не нужно помещать всю строку в структуру. Вы можете ссылаться на запрос по номеру строки (помните, что это 1, а не 0).

yourQueryName[yourColumnName][номер_строки]

<cfoutput>
     #mycontacts["Name"][13]#
     #mycontacts["HomePhone"][13]# 
</cfoutput>
person Mr.Black    schedule 10.05.2013

Сначала вы должны преобразовать запрос в структуру:

<cfscript>
    function GetQueryRow(query, rowNumber) {
        var i = 0;
        var rowData = StructNew();
        var cols = ListToArray(query.columnList);
        for (i = 1; i lte ArrayLen(cols); i = i + 1) {
            rowData[cols[i]] = query[cols[i]][rowNumber];
        }
        return rowData;
    }
</cfscript>

<cfoutput query="yourQuery">
    <cfset theCurrentRow = GetQueryRow(yourQuery, currentRow)>
    <cfdump var="#theCurrentRow#">
</cfoutput>

Надеюсь, это укажет вам правильное направление.

person andrewWinn    schedule 31.07.2009
comment
я тоже думал, что это единственный способ сделать это, пока не увидел ответ Патрика - person Kip; 01.08.2009

Я знаю, что возвращаюсь к этой теме каждый раз, когда я гуглю «обозначение скобки cfquery». Вот функция, которую я написал для обработки этого случая, используя запись в квадратных скобках. Надеюсь, это может помочь кому-то еще:

<cffunction name="QueryGetRow" access="public" returntype="array" hint="I return the specified row's data as an array in the correct order">
    <cfargument name="query" required="true" type="query" hint="I am the query whose row data you want">
    <cfargument name="rowNumber" required="true" hint="This is the row number of the row whose data you want">

    <cfset returnArray = []>
    <cfset valueArray = []>

    <cfset cList = ListToArray(query.ColumnList)>
    <cfloop from="1" to="#ArrayLen(cList)#" index="i">
        <cfset row = query["#cList[i]#"][rowNumber]>
        <cfset row = REReplace(row, "(,)", " ")>
        <cfset returnArray[i] = row>
        <cfset i++>
    </cfloop>   
    <cfreturn returnArray>
</cffunction>

REReplace является необязательным, он у меня есть для очистки запятых, чтобы он не испортил функцию arrayToList позже, если вам придется ее использовать.

person marta.joed    schedule 03.08.2011

Я хотел извлечь одну строку из запроса и сохранить имена столбцов (конечно). Вот как я это решил:

<cffunction name="getQueryRow" returntype="query" output="no">
    <cfargument name="qry" type="query" required="yes">
    <cfargument name="row" type="numeric" required="yes">
    <cfset arguments.qryRow=QueryNew(arguments.qry.columnlist)>
    <cfset QueryAddRow(arguments.qryRow)>
    <cfloop list="#arguments.qry.columnlist#" index="arguments.column">
        <cfset QuerySetCell(arguments.qryRow,arguments.column,Evaluate("arguments.qry.#arguments.column#[arguments.row]"))>
    </cfloop>
    <cfreturn arguments.qryRow>
</cffunction>
person YZE91    schedule 27.01.2012
comment
Спасибо! Я не знал о cflib - person YZE91; 28.01.2012

Описанные ранее методы получения данных запроса по имени столбца и номеру строки (variables.myquery["columnName"][rowNumber]) верны, но не удобны для получения полной строки данных запроса.

У меня Рейло 4.1. И это крутое решение. Жаль, что это нельзя сделать так, как хотелось бы, чтобы сразу получить полную строку данных, но следующий метод позволяет нам получить то, что мы хотим, через несколько обручей.

Когда вы serializeJSON(variables.myquery), он изменяет запрос на объект структуры cfml в формате JSON с двумя элементами: «Столбцы» и «Данные». Оба они являются массивами данных. Массив «данные» представляет собой двумерный массив для строк, а затем столбцовые данные.

Проблема в том, что теперь у нас есть непригодная для использования строка. Затем, если мы повторно сериализуем его, это будет НЕ запрос, а скорее полезная обычная структура в формате, описанном выше.

Предположим, у нас уже есть переменная запроса с именем 'variables.myquery'. Затем посмотрите на следующий код:

<cfset variables.myqueryobj = deserializeJSON(serializeJSON(variables.myquery)) />

Теперь вы получаете двумерный массив, получив это:

<cfset variables.allrowsarray = variables.myqueryobj.data />

И вы получаете один массив строк запроса, получая это:

<cfset variables.allrowsarray = variables.myqueryobj.data[1] />

ИЛИ последняя строка таким образом:

<cfset variables.allrowsarray = variables.myqueryobj.data[variables.myquery.recordCount] />

И вы можете получить значения отдельных столбцов с помощью итерации номера столбца:

<cfset variables.allrowsarray = variables.myqueryobj.data[1][1] />

Теперь это может быть медленным и, возможно, неразумным с большими результатами запроса, но, тем не менее, это классное решение.

person user2859532    schedule 08.10.2013

Ознакомьтесь с документацией по queryGetRow. . Он принимает объект запроса и индекс строки с первой строкой, на которую ссылается индекс 1 (НЕ 0). Индекс, используемый таким образом, должен быть положительным целым числом.

<cfquery name="QueryName" datasource="ds">
  SELECT *
  FROM tablename
</cfquery>

<!---
    This would retrieve the first record of the query
    and store the record in a struct format in the variable 'x'.
--->
<cfset x = queryGetRow(QueryName, 1) />
<!---
    This is an alternative using the member method form of queryGetRow
--->
<cfset x = QueryName.getRow(1) />
person cpetrich    schedule 03.03.2017
comment
Интересно, почему отрицательные голоса. Имеет два варианта правильного ответа. Подход с использованием функций-членов достаточно ясен. - person James A Mohler; 27.07.2018