2011-10-22 15 views
11
と挿入した後、テーブルのIDを取得します

一つのテーブルに挿入し、その後、私は別のテーブルに挿入できるように戻ってIDを取得するための私の通常のプロセスは、MSSQLでこのようなものです:ColdFusionとMySQLの

DECLARE @transactionKey uniqueidentifier 
SET @transactionKey = NEWID() 

INSERT INTO transactions(transactionKey, transactionDate, transactionAmount) 
    VALUES(@transactionKey, '#transactionDate#', '#transactionAmount#') 

DECLARE @transactionID int 
SELECT @transactionID = transactionID 
    FROM transactions 
    WHERE transactionKey = @transactionKey 


INSERT INTO transactionItems(transactionID, itemID, itemAmount) 
    VALUES(@transactionID, '#itemID#', '#itemAmount#') 


SELECT @transactionID as transactionID 

私の質問は2部。まず、これを行うにはこれが最善の方法ですか?私は、GUIDが私のところで変わる可能性があり、2番目のテーブルに無効なGUIDが入ることを読みました。私はそれが非常にスリムであると想定しており、何年も前からさまざまなプロジェクトでこれをやっており、問題は一度もなかった。

私の質問の2番目の部分は、MySQLでのこの作業のようなものですか?私はMySQLを使用して新しいプロジェクトに取り掛かり始めており、これを行う最善の方法は正確にはわかりません。私は通常、過去にMSSQLでしか働いていませんでした。

私はこの新しいプロジェクトでCF9とMySQLを使用しています。

これについての助力は素晴らしいことです。

ありがとうございます。

+0

Re:*私はGUIDが変更される可能性があることを読んだ*あなたはそれをどこで読んだのですか? – Leigh

答えて

23

パート1: SQLインジェクションのリスクを軽減するため、1つのクエリ内で複数のステートメントをバッチしないでください。これは、ColdFusion管理者のデータソース内の設定です。あなたが行っていることかもしれないストアドプロシージャ(?)を実行することはもう一つの話ですが、あなたの意図であれば、 "mySQLストアドプロシージャを挿入した後にプライマリキーを取得する"という言葉を改めてください。

パート2: - あなたは自動インクリメントキー、のGUIDまたはOracleのROWNUMのようなものを使用している場合でも ColdFusionには、多くのことのように、新たに挿入されたレコードの主キーは非常に簡単になってます。これは、MSSQLやMySQLを含むAdobe ColdFusionでサポートされているほとんどすべてのデータベースで動作します。唯一の例外は、データベースのバージョンです。例えば、MySQL 3はこれをサポートしません。しかし、MySQL 4+はそうします。

<cfquery result="result"> 
    INSERT INTO myTable (
     title 
) VALUES (
    <cfqueryparam value="Nice feature!" cfsqltype="cf_sql_varchar"> 
) 
</cfquery> 

<--- get the primary key of the inserted record ---> 
<cfset NewPrimaryKey = result.generatedkey> 

はCF9 +の時点で、あなたは、一般的なキー名を使用して(任意のデータベースのための)新しいIDにアクセスすることができます:CF8の場合は、異なるデータベースは、結果値内で異なる鍵を持っています

result.GENERATEDKEY // All databases 

。ここには、私がcfquery documentationからコピーするのに役立つ簡単な表があります。

result.identitycol // MSSQL 
result.rowid   // Oracle 
result.sys_identity // Sybase 
result.serial_col  // Informix 
result.generated_key // MySQL 

ご質問がありましたら、以下のように、あなたはかなりのダンプを見ることができます:ここで

<cfdump var="#result#" /> 
+0

"result"属性の場合は+1、cfqueryparamを使用した場合はクエリをより細かい呼び出しに分割します。 –

+0

@aaronありがとう!なぜ私はずっとそれを他の方法でやっているのか分かりません。これはずっと簡単です。 – Sequenzia

+0

私は理由を知りませんが、私はresult.generatedKeyを私のために働かせることができませんでした。 result.generated_keyを使用するとうまく動作します。 – Yisroel

1

は、MSSQLのための迅速なソリューションです。これは、前の挿入ステートメントに挿入された最後の行のIDを戻すSCOPE_IDENTITY()関数を使用します。

http://msdn.microsoft.com/en-us/library/ms190315.aspx

<cfquery> 
    DECLARE @iNewGeneratedID INT 

    INSERT INTO transactions 
     (
      transactionDate, 
      transactionAmount 
     ) 
    VALUES 
     (
      <cfqueryparam value="#transactionDate#" type="cf_sql_date">, 
      <cfqueryparam value="#transactionAmount#" type="cf_sql_integer"> 
     ) 

    SET @iNewGeneratedID = SCOPE_IDENTITY() 

    INSERT INTO transactionItems 
     (
      transactionID, 
      itemID, 
      itemAmount 
     ) 
    VALUES 
     (
      @iNewGeneratedID, 
      <cfqueryparam value="#itemID#" type="cf_sql_integer">, 
      <cfqueryparam value="#itemAmount#" type="cf_sql_integer"> 
     ) 

    SELECT @iNewGeneratedID AS iNewGeneratedID 
</cfquery> 
+0

ありがとう!私はこのやり方が私がやっていた他の方法よりも好きです。これはストアドプロシージャに適しています。 – Sequenzia

0

getGeneratedKey function at cflib.orgは、ほとんどのデータベースで使用できます。

例:@アーロン・グリーンリーの答えを1として

<cfquery name="insertArtist" datasource="cfartgallery" result="r"> 
    insert into artists (firstName, lastName) 
    values('todd','sharp') 
</cfquery> 
<cfquery name="getArtists" datasource="cfartgallery"> 
    select * 
    from artists 
</cfquery> 
<cfdump var="#getArtists#"> 
<cfoutput>#getGeneratedKey(r)#</cfoutput> 

<cffunction name="getGeneratedKey" 
    hint="I normalize the key returned from cfquery" output="false"> 

     <cfargument name="resultStruct" hint="the result struct returned from cfquery" /> 
     <cfif structKeyExists(arguments.resultStruct, "IDENTITYCOL")> 
      <cfreturn arguments.resultStruct.IDENTITYCOL /> 
     <cfelseif structKeyExists(arguments.resultStruct, "ROWID")> 
      <cfreturn arguments.resultStruct.ROWID /> 
     <cfelseif structKeyExists(arguments.resultStruct, "SYB_IDENTITY")> 
      <cfreturn arguments.resultStruct.SYB_IDENTITY /> 
     <cfelseif structKeyExists(arguments.resultStruct, "SERIAL_COL")> 
      <cfreturn arguments.resultStruct.SERIAL_COL /> 
     <cfelseif structKeyExists(arguments.resultStruct, "GENERATED_KEY")> 
      <cfreturn arguments.resultStruct.GENERATED_KEY /> 
     <cfelse> 
      <cfreturn /> 
     </cfif> 
</cffunction> 
0

、 r INSERTクエリのesult変数には、挿入された行の自動的に生成されたIDであるキーと値のペアが含まれています。 this is available only for databases that support this feature.

また、挿入されたレコードをすべてのデータベースに対して返すことができます。

<cfquery result="result"> 
    INSERT INTO myTable (
     title 
    ) 
    OUTPUT INSERTED.* 
    VALUES (
    <cfqueryparam value="Nice feature!" cfsqltype="cf_sql_varchar"> 
    ) 
</cfquery> 

結果に挿入されたレコードの詳細が表示されます。

これが役に立ちます。ありがとう。