2011-10-22 2 views
11

Mon processus normal pour l'insertion dans une table, puis obtenir l'ID de retour afin que je puisse l'insérer dans une autre table est comme ça dans MSSQL:Obtenir ID de table après insertion avec ColdFusion et 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 

Ma question est 2 parties Premièrement, est-ce la meilleure façon de faire cela? J'ai lu qu'il y a une chance que le GUID change sur moi et je me retrouve avec un GUID invalide dans la deuxième table. Je suppose que les chances sont minces et je fais cela depuis des années sur divers projets et je n'ai jamais eu de problème.

La deuxième partie de ma question est quelque chose comme ce travail dans MySQL? Je commence à travailler sur un nouveau projet en utilisant MySQL et je ne suis pas sûr de la meilleure façon de le faire. Je n'ai normalement travaillé que sur MSSQL par le passé. J'utilise CF9 et MySQL sur ce nouveau projet.

Toute aide sur ce serait génial.

Merci d'avance.

+0

Re: * J'ai lu qu'il y a une chance que le GUID change sur moi * Où avez-vous lu cela? – Leigh

Répondre

23

Partie 1: Personnellement, je ne traiterais pas plusieurs instructions au sein d'une même requête afin de réduire le risque d'injection SQL. C'est un paramètre dans votre source de données sur l'administrateur ColdFusion. L'exécution d'une procédure stockée, qui pourrait être ce que vous faites (?), Est une autre histoire, mais, vous devriez reformuler votre question à "Obtenir la clé primaire après insertion avec mySQL Stored Procedure" si c'est votre intention.

Partie 2: ColdFusion, comme beaucoup de choses, fait obtenir la clé primaire pour un enregistrement inséré très facile - même si vous utilisez les touches auto-incrément, ou GUIDs quelque chose comme ROWNUM d'Oracle. Cela fonctionnera sur n'importe quelle base de données supportée par Adobe ColdFusion, y compris MSSQL ou MySQL. La seule exception est la version de la base de données - par exemple, MySQL 3 ne supportera pas cela; cependant, MySQL 4+ le fera.

<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> 

Au CF9 +, vous pouvez accéder à la nouvelle ID (pour une base de données) en utilisant le nom de clé générique:

result.GENERATEDKEY // All databases 

Pour CF8, bases de données différentes auront des clés différentes dans la valeur des résultats. Voici un tableau simple pour aider j'ai copié du cfquery documentation.

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

Si vous avez des questions vous pouvez voir une jolie décharge comme suit:

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

+1 pour l'attribut "result", en utilisant cfqueryparam, et en séparant les requêtes en appels plus granulaires. –

+0

@aaron Merci! Je ne sais pas pourquoi je l'ai fait depuis si longtemps. C'est beaucoup plus facile. – Sequenzia

+0

Je ne sais pas pourquoi, mais je n'ai jamais pu obtenir result.generatedKey pour travailler pour moi. L'utilisation de result.generated_key fonctionne correctement. – Yisroel

1

Voici une solution rapide pour MSSQL. Il utilise la fonction SCOPE_IDENTITY() qui renvoie l'ID de la dernière ligne insérée dans l'instruction d'insertion précédente.

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

merci! J'aime mieux cette façon que l'autre. Ce sera bon pour les procédures stockées. – Sequenzia

0

Le getGeneratedKey function at cflib.org peut être utilisé avec la plupart des bases de données:

Exemple:

<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

Selon la réponse de @ aaron-Greenlee, Le r La variable esult des requêtes INSERT contient une paire clé-valeur qui est l'ID généré automatiquement de la ligne insérée; this is available only for databases that support this feature.

Et ce qui est ci-dessous est possible de retourner l'enregistrement inséré pour toutes les bases de données.

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

Vous obtiendrez les informations sur l'enregistrement inséré dans le résultat.

Espérons que cela aide. Merci.

Questions connexes