Получение первичного ключа записей, которые я только что вставил - PullRequest
0 голосов
/ 27 апреля 2011

Это становится довольно сложно.Я хочу вывести первичный ключ только что вставленной записи.Я делаю вставку из нескольких записей:

Моя инструкция вставки выглядит примерно так:

<cfquery name="imprtFiles" datasource="#mydsn#" result="#result#">
    <cfoutput query="myFileList">
        INSERT INTO myTablename (mycolumn) VALUES ('#valuegohere#');
    </cfoutput>
</cfquery>

<cfset newID = result.IdentityCol>
<cfoutput>#newID#</cfoutput>

И это выдает ошибку CF:

"ЭлементIDENTITYCOL не определен в RESULT. "

Так что я думаю, что есть еще один способ получить PK записи, которую я только что вставил.Какие-нибудь мысли?

Вот код, который я использовал в соответствии с примером:

<cftransaction>
    <cfquery name="importFiles" datasource="#dsn#" result="result">
        <cfoutput query="myFileList">
        INSERT INTO tbl_logfiles (originalFile, originalFileSize) VALUES ('#name#', '#length#');
        </cfoutput>
    </cfquery>

    <cfquery name="getID" datasource="#dsn#">
         select Max(fileID) as NewID from tbl_logfiles;
    </cfquery>
</cftransaction>

<cfset newID = getID.NewID>
<cfoutput> #newID# </cfoutput>

Вывод, полученный из #newID#, равен 280, что является наибольшим значением fileID в моей таблице базы данных на данный момент.Странно.

Я пытаюсь получить последние 1010 * записей, которые я импортировал.Я надеялся, что есть способ как-то вывести его из тега cfoutput на основе cfquery.result.

Ответы [ 4 ]

4 голосов
/ 25 сентября 2013

Я знаю, что это старый поток, но ... никогда не используйте SELECT MAX(Column) для получения последнего вставленного идентификатора. Это не потокобезопасно даже внутри транзакции (установлено на уровне по умолчанию).

Поскольку атрибут result возвращает только одно значение идентификатора, вывместо этого необходимо использовать отдельные запросы (для SQL Server 2000 в любом случае).Затем вы можете получить и сохранить новый идентификатор после каждого insert.

Кроме того, обязательно используйте cfqueryparam для всех параметров.В дополнение к защите от внедрения SQL, он повысит производительность запросов insert, побуждая базу данных повторно использовать тот же план запросов .

<cfset newIDArray = []>
<cftransaction>
    <cfloop query="myFileList">
        <cfquery result="result" ...>
           INSERT INTO myTablename (...) VALUES (...);
        </cfquery>
        <!--- For CF9+ use generic result.generatedKey instead --->
        <cfset arrayAppend(newIDArray, result.identityCol)>
    </cfloop>
</cftransaction>

Примечание. Как упомянул Николас вВ комментариях CF9 + введено новое независимое от базы данных имя ключа result.generatedKey.Поэтому, если вы используете более позднюю версию, это имя ключа предпочтительнее, чем result.identityCol, для большей гибкости.

Очевидно, что есть улучшенных опций, таких как OUTPUT для SQL Server 2005 .

1 голос
/ 27 апреля 2011

Это будет MSSQL 2000 или 2005. Если вы используете 2005, вы можете использовать предложение OUTPUT в запросе INSERT, чтобы отслеживать значения PK, созданные вставкой.

См. Эту статью BOLПодробнее о OUTPUT .

Чтобы использовать это в своем решении, вам, возможно, придется настроить его как хранимую процедуру и вызвать SP из CF.

0 голосов
/ 27 апреля 2011

Я думаю, что в этом случае вам нужно сделать каждую из вставок в своем собственном теге cfquery. Если бы вы делали одну вставку за раз, это не было бы проблемой, но поскольку вы выполняете несколько вставок (и вы используете более старую версию SQL Server), нет способа сделать это с одной cfquery. Если вы находитесь на 2005 или 2008, вы могли бы потенциально использовать метод OUTPUT, упомянутый в другом ответе.

0 голосов
/ 27 апреля 2011

Существуют различные способы сделать это в Coldfusion - проверьте это здесь: http://tutorial480.easycfm.com/

EDIT:

Попробуйте этот метод, он точно будет работать:


<cftransaction>
<cfquery name="imprtFiles" datasource="#mydsn#" result="#result#">
<cfoutput query="myFileList">
INSERT INTO myTablename (mycolumn) VALUES ('#valuegohere#');
</cfoutput>
</cfquery>
<cfquery name="getID" datasource="#mydsn#" result="#result#">
select Max(id) as NewID from myTablename;
</cfquery>
</cftransaction>
<cfset newID = getID.NewID&gt
<cfoutput>
#newID#
</cfoutput>

РЕДАКТИРОВАТЬ на основе комментария:

Да, конечно. У вас есть запрос cfoutput в теге cfquery, поэтому вы вставляете строку за строкой и каждый раз создаете новый идентификатор. Если вам нужны идентификаторы для каждого из них, вам нужно обернуть все это в свой cfoutput:


<cftransaction>
<cfoutput query="myFileList">
<cfquery name="imprtFiles" datasource="#mydsn#" result="#result#">
INSERT INTO myTablename (mycolumn) VALUES ('#valuegohere#');
</cfquery>
<cfquery name="getID" datasource="#mydsn#" result="#result#">
select Max(id) as NewID from myTablename;
</cfquery>
<cfset newID = getID.NewID&gt
#newID#
</cfoutput>
</cftransaction>
...