เลือก SQL Server เป็น @variable หรือไม่


250

ฉันมีรหัสต่อไปนี้ในหนึ่งใน Sql ของฉัน (2008) Procs ที่เก็บไว้ซึ่งดำเนินการได้อย่างสมบูรณ์แบบ:

    CREATE PROCEDURE [dbo].[Item_AddItem]
        @CustomerId uniqueidentifier,
        @Description nvarchar(100),
        @Type int,
        @Username nvarchar(100),
    AS
    BEGIN

        DECLARE @TopRelatedItemId uniqueidentifier;
        SET @TopRelatedItemId = 
        (
           SELECT top(1) RelatedItemId 
           FROM RelatedItems 
           WHERE CustomerId = @CustomerId
        ) 

        DECLARE @TempItem TABLE
        (
            ItemId uniqueidentifier,
            CustomerId uniqueidentifier,
            Description nvarchar(100),
            Type int,
            Username nvarchar(100),
            TimeStamp datetime
        );

        INSERT INTO Item
        OUTPUT INSERTED.* INTO @TempItem
        SELECT NEWID(), @CustomerId, @Description, @Type, @Username, GETDATE()

        SELECT
            ItemId,
            CustomerId,
            @TopRelatedItemId,
            Description,
            Type,
            Username,
            TimeStamp
        FROM
            @TempItem
END
GO

ดังนั้นคำถามสำหรับพวกคุณคือมีความเป็นไปได้ที่จะทำอะไรสักอย่างตามแนวของ:

DECLARE @TempCustomer TABLE
(
   CustomerId uniqueidentifier,
   FirstName nvarchar(100),
   LastName nvarchar(100),
   Email nvarchar(100)
);
SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email 
INTO 
    @TempCustomer 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId

เพื่อที่ฉันจะสามารถใช้ข้อมูลนี้จากหน่วยความจำในคำสั่งอื่น ๆ ต่อไปนี้? SQL Server พ่นคำสั่งด้านบนได้อย่างเหมาะสม แต่ฉันไม่ต้องการสร้างตัวแปรแยกต่างหากและเริ่มต้นแต่ละคำสั่งด้วยคำสั่ง SELECT แบบแยกจากตารางเดียวกัน .... UGH !!!

ข้อเสนอแนะเกี่ยวกับวิธีการบรรลุบางสิ่งบางอย่างตามบรรทัดโดยไม่ต้องมีหลายแบบสอบถามเทียบกับตารางเดียวกัน


1
"เพื่อสร้างตัวแปรแยกและกำหนดค่าเริ่มต้นแต่ละตัวผ่านคำสั่ง SELECT แยก" - ทำไมคุณต้องทำเช่นนั้น? declare @t tableหนึ่งครั้งและหากคุณต้องการนำมาใช้ซ้ำให้ยิง a DELETE @TempCustomerก่อนใส่เข้าไปอีกครั้ง
RichardTheKiwi

คำตอบ:


204

คุณไม่สามารถเลือก .. เข้า .. ตารางต่างๆ สิ่งที่ดีที่สุดที่คุณสามารถทำได้คือสร้างมันขึ้นมาก่อนจากนั้นจึงใส่เข้าไป ตัวอย่างที่สองของคุณจะต้องเป็น

DECLARE @TempCustomer TABLE
(
   CustomerId uniqueidentifier,
   FirstName nvarchar(100),
   LastName nvarchar(100),
   Email nvarchar(100)
);
INSERT INTO 
    @TempCustomer 
SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId

5
ควรทราบว่าวิธีนี้ใช้ได้ผลดีในบริบท CTE เช่นกัน Bazinga!
Michael Krauklis

4
ทุกคนมีคำตอบว่าทำไมไม่มีใครเลือกเป็นตัวแปรตารางอย่างที่คุณสามารถทำได้ด้วยตารางชั่วคราวจริง
KSwift87

504

หากคุณต้องการกำหนดตัวแปรบางอย่างเพื่อการใช้งานในภายหลังคุณสามารถทำสิ่งเหล่านี้ในช็อตเดียวโดยใช้บางสิ่งบางอย่างตามบรรทัดเหล่านี้:

declare @var1 int,@var2 int,@var3 int;

select 
    @var1 = field1,
    @var2 = field2,
    @var3 = field3
from
    table
where
    condition

ถ้านั่นคือประเภทของสิ่งที่คุณตามมา


1
คำตอบที่ดีที่สุดคืออะไร แต่จะเกิดอะไรขึ้นถ้าผลลัพธ์มีมากกว่าหนึ่ง
capitano666

หากผลลัพธ์มากกว่าหนึ่งคุณจะได้รับหนึ่งในค่าที่มีอยู่ นั่นอาจเป็นปริศนาที่น่าสนใจ! ดู mssqltips.com/sqlservertip/1888/…
Smandoli

8
ในการบังคับให้คิวรีส่งคืนแถวเดียวให้ใช้ SELECT TOP 1
Adrian

1
@Adrian ใช่ข้อความค้นหาด้านบนถือว่าคุณได้เลือกแถวเดียวแล้ว คุณสามารถใช้ฟังก์ชั่นการสั่งซื้อและการรวมหากคุณต้องการตรรกะแฟนซีเพิ่มเติม
dougajmcdonald

1
ในกรณีที่คุณไม่ได้ใช้ประเภทฐานข้อมูลที่ OP ใช้อยู่ไม่สนับสนุน TOP 1 ทั้งหมดตามที่เอเดรียนกล่าวไว้ SQL Server / MS Access ใช้ TOP, MySQL ใช้ LIMIT และ Oracle ใช้ ROWNUM ดูw3schools.com/sql/sql_top.aspสำหรับข้อมูลเพิ่มเติม
Tyler

33

คุณสามารถทำสิ่งนี้:

SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email
INTO #tempCustomer 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId

หลังจากนั้น

SELECT CustomerId FROM #tempCustomer

คุณไม่จำเป็นต้องประกาศโครงสร้างของ #tempCustomer


3
@webturner ไม่มีจุดใดที่เป็นจริง ตารางชั่วคราวไม่ได้ถูกกำหนดขอบเขตไว้ด้านนอกของตัวแปร proc และตารางไม่ได้เป็น "หน่วยความจำเท่านั้น" มากกว่าตารางชั่วคราว
Martin Smith

7
อย่าลืมที่จะเพิ่มDROP TABLE #tempCustomerเวลาที่#tempCustomerไม่จำเป็นอีกต่อไปมิฉะนั้นตัวเลือกถัดไปจะทำให้เกิด#tempCustomer already existsข้อผิดพลาด
ViRuSTriNiTy

15

ดูเหมือนว่าไวยากรณ์ของคุณจะออกมาเล็กน้อย นี่เป็นตัวอย่างที่ดี

DECLARE @TempCustomer TABLE
(
   CustomerId uniqueidentifier,
   FirstName nvarchar(100),
   LastName nvarchar(100),
   Email nvarchar(100)
);
INSERT @TempCustomer 
SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId

จากนั้นต่อมา

SELECT CustomerId FROM @TempCustomer

2

ดูเหมือนว่าคุณต้องการตารางชั่วคราว http://www.sqlteam.com/article/temporary-tables

โปรดทราบว่า #TempTable มีให้บริการตลอด SP ของคุณ

หมายเหตุ ## TempTable มีให้สำหรับทุกคน


2
## ล่อลวง - จนกว่าเจ้าของ (ผู้สร้าง) ลบมันหรือถูกตัดการเชื่อมต่อ
RichardTheKiwi

4
ฉันไม่ต้องการตารางชั่วคราว ตารางชั่วคราวแพงและช้า ฉันต้องการเก็บข้อมูลเล็กน้อยสำหรับบันทึกที่ระบุในเวลาเพียงเล็กน้อยและทำให้ใช้ได้กับคำสั่ง sql หลายรายการโดยไม่ต้องค้นหาต่อไป เนื่องจากตัวแปรตารางมีขอบเขตภายใน proc ที่จัดเก็บไว้ซึ่งถูกกำหนดไว้ในพวกเขาจึงเป็นโซลูชั่นที่สมบูรณ์แบบสำหรับการจัดเก็บข้อมูล tuppled สำหรับการโทร proc ที่เก็บไว้หนึ่ง ...
ดาวน์โหลด

3
ฉันลืมที่จะพูดถึงว่าฐานข้อมูลอยู่ใน Azure .... ฉันไม่ต้องการแนะนำระเบียบจากการจัดการตารางอุณหภูมิ
bleepzter

ตารางตัวแปรเป็นวิธีที่จะไป ประกาศ @varTable Table (.... )
ARLibertarian

1

ฉันพบคำถามของคุณที่กำลังมองหาวิธีแก้ไขปัญหาเดียวกัน และคำตอบอื่น ๆ ที่ล้มเหลวในการชี้เป็นวิธีการใช้ตัวแปรเพื่อเปลี่ยนชื่อของตารางสำหรับการดำเนินการตามขั้นตอนของคุณทุกครั้งในรูปแบบถาวรไม่ใช่ชั่วคราว

จนถึงสิ่งที่ฉันทำคือการเชื่อมโยงรหัส SQL ทั้งหมดกับตัวแปรที่จะใช้ แบบนี้:

declare @table_name as varchar(30)
select @table_name = CONVERT(varchar(30), getdate(), 112)
set @table_name = 'DAILY_SNAPSHOT_' + @table_name

EXEC('
        SELECT var1, var2, var3
        INTO '+@table_name+'
        FROM my_view
        WHERE string = ''Strings must use double apostrophe''
    ');

ฉันหวังว่ามันจะช่วยได้ แต่มันอาจยุ่งยากถ้ารหัสมีขนาดใหญ่เกินไปดังนั้นหากคุณพบวิธีที่ดีกว่านี้โปรดแชร์!


-2
"SELECT *
  INTO 
    @TempCustomer 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId"

ซึ่งหมายถึงการสร้าง@tempCustomertablevariable ใหม่และการแทรกข้อมูลจากลูกค้า คุณได้ประกาศแล้วข้างต้นจึงไม่จำเป็นต้องประกาศอีกครั้ง ดีกว่าไปด้วย

INSERT INTO @tempCustomer SELECT * FROM Customer

4
มันไม่ทำงาน คุณยังต้องประกาศตัวแปรตารางล่วงหน้า
Johan Boulé
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.