2011-10-22 31 views
11

quá trình bình thường của tôi cho chèn vào một bảng và sau đó nhận được ID trở lại để tôi có thể chèn vào bảng khác là như thế này trong MSSQL:Nhận bảng ID sau khi chèn với ColdFusion và 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 

Câu hỏi của tôi là 2 phần. Đầu tiên, đây có phải là cách tốt nhất để làm điều này không? Tôi đọc rằng có một cơ hội mà GUID thay đổi trên tôi và tôi kết thúc với một GUID không hợp lệ trong bảng thứ hai. Tôi giả định rằng cơ hội đó rất mỏng và tôi đã làm điều này trong nhiều năm về các dự án khác nhau và chưa bao giờ có vấn đề gì cả.

Phần thứ hai của câu hỏi của tôi là hoạt động như thế này trong MySQL? Tôi bắt đầu làm việc trên một dự án mới bằng cách sử dụng MySQL và tôi không chắc chắn chính xác cách tốt nhất để làm điều này. Tôi đã thường chỉ làm việc trên MSSQL trong quá khứ.

Tôi đang sử dụng CF9 và MySQL cho dự án mới này.

Bất kỳ trợ giúp nào về điều này đều tuyệt vời.

Xin cảm ơn trước.

+0

Re: * Tôi đọc rằng có một cơ hội mà GUID thay đổi về tôi * Bạn đã đọc ở đâu? – Leigh

Trả lời

23

Phần 1: Cá nhân tôi sẽ không bó nhiều câu lệnh trong một truy vấn để giảm nguy cơ tiêm SQL. Đây là cài đặt trong nguồn dữ liệu của bạn trên quản trị viên ColdFusion. Thực hiện một thủ tục lưu trữ, có thể là những gì bạn đang làm (?), Là một câu chuyện khác, nhưng, bạn nên rephrase câu hỏi của bạn để "Lấy khóa chính sau khi chèn với mySQL Stored Procedure" nếu đó là ý định của bạn.

Phần 2: ColdFusion, giống như nhiều thứ, làm cho nhận được chìa khóa chính cho một kỷ lục mới được chèn vào rất dễ dàng - ngay cả khi bạn đang sử dụng phím auto-increment, GUID hoặc một cái gì đó giống như ROWNUM của Oracle. Điều này sẽ làm việc trên bất kỳ gần như mọi cơ sở dữ liệu được hỗ trợ bởi Adobe ColdFusion bao gồm MSSQL hoặc MySQL. Ngoại lệ duy nhất là phiên bản của databse - ví dụ, MySQL 3 sẽ không hỗ trợ điều này; tuy nhiên, MySQL 4+ sẽ.

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

Tính đến CF9 +, bạn có thể truy cập vào các ID mới (đối với bất kỳ cơ sở dữ liệu) bằng cách sử dụng tên chìa khóa chung chung:

result.GENERATEDKEY // All databases 

Đối CF8, cơ sở dữ liệu khác nhau sẽ có các phím khác nhau trong giá trị kết quả. Đây là một bảng đơn giản để giúp tôi sao chép từ số cfquery documentation.

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

Nếu bạn có bất kỳ câu hỏi mà bạn có thể thấy một bãi chứa khá như sau:

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

+1 cho thuộc tính "kết quả", sử dụng cfqueryparam và chia các truy vấn thành các cuộc gọi chi tiết hơn. –

+0

@aaron Cảm ơn! Tôi không biết tại sao tôi lại làm nó theo cách khác quá lâu. Điều này dễ hơn rất nhiều. – Sequenzia

+0

Tôi không biết tại sao, nhưng tôi chưa bao giờ có thể nhận được result.generatedKey để làm việc cho tôi. sử dụng result.generated_key hoạt động tốt. – Yisroel

1

Dưới đây là một giải pháp nhanh chóng cho MSSQL. Nó sử dụng hàm SCOPE_IDENTITY() trả về ID của hàng cuối cùng được chèn vào trong câu lệnh chèn trước đó.

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

cảm ơn! Tôi thích cách này cũng tốt hơn cách khác tôi đã làm nó. Điều này sẽ tốt cho các thủ tục được lưu trữ. – Sequenzia

0

Các getGeneratedKey function at cflib.org thể được sử dụng với hầu hết các cơ sở dữ liệu:

Ví dụ:

<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

Theo câu trả lời của @ aaron-Greenlee, R biến esult của truy vấn INSERT chứa cặp khóa-giá trị là ID được tạo tự động của hàng được chèn; this is available only for databases that support this feature.

Và dưới đây là cách có thể để trả về bản ghi được chèn cho tất cả các cơ sở dữ liệu.

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

Bạn sẽ nhận được chi tiết bản ghi được chèn vào kết quả.

Hy vọng điều này sẽ hữu ích. Cảm ơn.

Các vấn đề liên quan