Variabel Deklarasi SQL

Adakah yang bisa memeriksa pernyataan saya...

DECLARE @tblName varchar(MAX), 
        @strSQL varchar(MAX)

SET @tblName ='SELECT DISTINCT o.name as TableName 
                 FROM sysobjects o 
                 JOIN sysindexes x on o.id = x.id  
                WHERE o.name LIKE ''%empty%'''  

SET @strSQL = 'INSERT INTO @tblName VALUES(''trylng'', ''1'')'
EXEC (@strSQL)

kesalahanku adalah...

Pesan 1087, Level 15, Status 2, Baris 1
Harus mendeklarasikan variabel tabel "@tblName".


person Argel Joseph    schedule 23.02.2012    source sumber
comment
Saya harap hanya ada dua kolom di tabel apa pun yang dikembalikan, dan tipe datanya cocok...   -  person OMG Ponies    schedule 23.02.2012
comment
@OMGPonies: Maksud Anda kolom yang dapat disisipkan, tentu saja.   -  person Andriy M    schedule 23.02.2012


Jawaban (2)


Properti @tblName Anda ada di cakupan luar - cakupan baris kode "normal" Anda - tetapi tidak di cakupan dalam SQL yang Anda buat dalam string di sana....

Anda perlu mengubah baris Anda untuk membaca:

SET @strSQL = 'INSERT INTO ' + @tblName + ' VALUES(''trylng'', ''1'')'

dan kemudian itu akan berfungsi dengan baik.

Selain itu, Anda tidak menyebutkan versi SQL Server Anda - tetapi mulai SQL Server 2005 atau yang lebih baru, Anda harus berhenti menggunakan sysobjects dan sysindexes - sebagai gantinya, gunakan skema sys baru yang berisi informasi yang kurang lebih sama - tetapi lebih mudah tersedia. Ubah kueri Anda menjadi:

SET @tblName ='SELECT DISTINCT t.name as TableName 
               FROM sys.tables t
               INNER JOIN sys.indexes i on i.object_id = t.object_id  
               WHERE t.name LIKE ''%empty%'''  

Lihat MSDN: Mengkueri Katalog Sistem SQL Server untuk informasi lebih lanjut tentang apa yang tersedia di skema sys baru dan cara memanfaatkannya semaksimal mungkin!

Seperti yang ditunjukkan oleh "rsbarro": memasukkan pernyataan SQL ini ke dalam tanda kutip adalah hal yang aneh - apakah Anda juga menjalankan pernyataan ini menggunakan EXEC(...)?? Tapi lalu bagaimana Anda mengembalikan nilai ke properti @tblName? Benar-benar tidak masuk akal.....

Jika Anda ingin menjalankan kueri ini untuk mendapatkan nilai, Anda harus memiliki sesuatu seperti ini:

 SELECT TOP 1 @tblName = t.name
 FROM sys.tables t
 INNER JOIN sys.indexes i on i.object_id = t.object_id  
 WHERE t.name LIKE '%empty%'

Anda harus memiliki TOP 1 di sana untuk yakin mendapatkan satu nilai saja - jika tidak, pernyataan ini bisa gagal (jika beberapa baris dipilih).

person marc_s    schedule 23.02.2012
comment
Apakah saya melewatkan sesuatu? Mengapa @tblName dibungkus dengan tanda kutip tunggal? Bukankah itu hanya akan mengaturnya sama dengan string, dan bukan nama tabel? - person rsbarro; 23.02.2012
comment
Tidak, maksud saya pernyataan kedua. Bukankah seharusnya dibaca SET @tblName = SELECT DISTINCT t.name... tanpa tanda kutip? Cara penulisannya @strSQL akan memiliki nilai INSERT INTO SELECT DISTINCT t.Name as TableName.... Menurut saya itu tidak valid, bukan? - person rsbarro; 23.02.2012
comment
@rsbarro: ah oke - baiklah, tidak yakin - Saya berasumsi OP akan mengeksekusi pernyataan SQL itu menggunakan EXEC(....) juga. Jika tidak, maka Anda benar, itu tidak akan berhasil! - person marc_s; 23.02.2012
comment
Dingin. Saat itu aku sudah larut malam, dan kupikir aku melihat sintaksis baru atau kehilangan akal... =] - person rsbarro; 23.02.2012
comment
Pertanyaan lain...mengapa kita perlu menggunakan join ke SYS.INDEXES karena pada daftar tabel yang cocok dengan WHERE kita ada di SYS.TABLES..?? - person Argel Joseph; 28.02.2012
comment
@ArgelJoseph: Saya tidak tahu mengapa Anda menggunakan sys.indexes - itu pernyataan Anda, saya hanya mencoba membuatnya berfungsi. Tapi Anda benar - sys.indexes sepertinya tidak dibutuhkan di sini dalam pernyataan itu.... - person marc_s; 28.02.2012

Tidak yakin persis apa yang ingin Anda lakukan, tapi menurut saya Anda menginginkan sesuatu seperti ini:

DECLARE @tblName varchar(MAX), @strSQL varchar(MAX)
SET @tblName = 
    (select distinct o.name as TableName 
     from sysobjects o 
     join sysindexes x on o.id = x.id  
     where o.name LIKE '%empty%')
SET @strSQL = 'INSERT INTO [' + @tblName + '] VALUES(''trylng'', ''1'')'
exec (@strSQL)

Meskipun demikian, masih ada beberapa hal yang harus diperhatikan di sini. Anda perlu menangani kondisi di mana SELECT DISTINCT mengembalikan apa pun selain satu catatan. Selain itu, saya tidak begitu memahami perlunya membangun SQL dinamis (di @strSQL) ketika @tblName akan selalu memiliki nilai yang sama (karena tidak ada variabel yang digunakan dalam klausa WHERE).

person rsbarro    schedule 23.02.2012
comment
+1, hanya satu catatan: umumnya lebih aman untuk memasukkan nama ke dalam skrip dinamis seperti ini: 'INSERT INTO ' + QUOTENAME(@tblName) + '…', daripada hanya memberi tanda kurung siku di sekelilingnya. - person Andriy M; 23.02.2012