2012-07-30 14 views
3

我有一個存儲過程與輸出一行的SELECT語句。它是這樣的:哪裏是選擇查詢值臨時存儲,以及如何分別獲取每個值

CREATE PROCEDURE [dbo].[CreateCustomer] 
... 

INSERT INTO Customers values(, , , ,) 
SELECT CustomerID, FirstName, LastNam..... 
INSERT Roles values(, , , ..... 

這將選擇新存儲的值從Customers表背。第二個插入使用新的CustomerID將新行插入Roles表。

有沒有辦法從上述select語句中獲取customerID而不再查詢CustomerID?

我試圖聲明一個變量,像這樣做:

SELECT takenCustomerID = CustomerID, FirstName, LastNam....(rest of query statement) 

但我要聲明的所有變量和這樣來做:

SELECT takenCustomerID, takenFirstName, takenLastNa... = CustomerID, FirstName, LastNam... (rest of query statement) 

但是,我認爲這是不好的,因爲它會浪費服務器端的大量內存。

那麼,是否有一種簡單的方法可以在不聲明select語句中的所有變量的情況下立即獲取各個值,例如可以調用TEMP(「customerID」)的內置類TEMP變量並獲取該值?

另外,在存儲過程中是否可以有多個SELECT語句?我們如何從我們想要的select語句中獲取選擇值?

我更多的是出於好奇,因爲我已經知道一種獲得價值的方法。我只想知道是否有更優雅的方式。

+0

你*必須*做一個單獨的'SELECT'(即你以後再次使用SP值嗎?)?如果沒有,您可以改爲執行'INSERT INTO Roles SELECT ... FROM ...'。 – 2012-07-30 06:30:05

+1

那它是什麼,SQL Server或MySql?根據您的DBMS,答案將完全不同。 – ErikE 2012-07-30 06:30:20

+0

@Ic:我想要我插入的所有值返回並使用從選擇查詢中獲得的GUID將角色插入到角色表中 – 2012-07-30 06:35:03

回答

2

訪問插入的值

這很簡單。使用OUTPUT子句返回剛剛創建的值。

DECLARE @Customers TABLE (
    CustomerID uniqueidentifier, 
    FirstName varchar(100), 
    LastName varchar(100) 
); 

INSERT dbo.Customers 
OUTPUT Inserted.* 
INTO @Customers 
SELECT newsequentialid(), @FirstName, @LastName, ...; 
-- now you have all the values of the new row in the `@Customers` table variable. 

然後,你可以這樣做:

INSERT dbo.Roles 
SELECT 
    CustomerID, 
    @OtherValue, 
    @AnotherValue, 
    [email protected] 
FROM @Customers; 

如果您有從插入的客戶行的值不再使用,你甚至可以廢除表變量,只是直接輸出到角色表,假設所有的值都來自變量。

OUTPUT子句允許使用特殊元表Inserted訪問插入的值。但是,您也可以使用常量的變量和表達式。

使用此方法的好處在於您可以一次處理多個插入的行。如果插入只有一行,你只需要CustomerID之後,你需要使用它不止一次,則不用做這種方式:

DECLARE @CustomerID uniqueidentifier = newsequentialid(); 
INSERT @Customer VALUES (@CustomerID, ...); 
INSERT @Roles VALUES (..., @CustomerID ...); 

通過事先創建GUID,你不需要將其從表格中取出。順便說一下,如果它是聚集索引(這可能是真的),newsequentialid()可能優於newid(),因爲您將避免newid會導致的頁面拆分。

返回多個結果集

這始終是可能的。無論用什麼方法查詢,都會有一種方法將數據訪問對象提升到下一個記錄集。如果您使用的是DataReader,請查看NextResult方法。在Classic ADO中,記錄集有一個NextRecordset方法。

+0

謝謝ErikE ,,非常感謝這工作 – 2012-07-30 07:04:43

+0

我想馬克的帖子幫助更多? :) – ErikE 2012-07-30 07:12:18

+0

是啊:)我學到了很多東西。 Thaks無論如何ErikE – 2012-07-30 07:17:43

2

除非您手動將其重定向到表格,否則SELECT將僅轉到輸出流,因此否:您無法自動訪問先前選擇的值。

威力只是在尋找SCOPE_IDENTITY()

declare @id int 

insert .... 
values (...) 

set @id = SCOPE_IDENTITY() 

在DML一般情況下,另一位候選人是OUTPUT clause

對於更一般的複合器基於現有的選擇,一個表變量可以幫助:

declare @foo table (id int not null, name nvarchar(100) not null) // etc 

insert @foo (id, name) 
select id, name from Foo where ... 

select * from @foo // for output 

// but we still have the @foo data available for subsequent query 

... // more TSQL here 

隨着多個SELECT語句,這完全取決於你所使用的API;然而,這裏的原始ADO.NET API是IDataReader,它有NextResult()方法。多格典型用法是:

using(var reader = cmd.ExecuteReader()) { 
    do { 
     while(reader.Read()) { 
      // i.e. for each row in this grid 
      ... 
     } 
    } while (reader.NextResult()); // <== for each grid 
} 

while(...) {...}do {...} while(...)這裏的區別是因爲你自動開始在第一格,但是你需要在電網進步到第一行手動。

+0

謝謝Marc Gravell,這真是一個很好的答案。 – 2012-07-30 07:04:03

相關問題