Saya memiliki tabel tes sederhana seperti ini:
CREATE TABLE MyTable (x INT);
Dalam suatu transaksi, saya mencoba untuk menambahkan kolom dan kemudian memasukkan ke dalam kolom yang baru dibuat:
BEGIN TRANSACTION;
PRINT 'Adding column, ''SupplementalDividends'', to MyTable table.';
ALTER TABLE MyTable
ADD SupplementalDividends DECIMAL(18,6);
PRINT 'Column added successfully....';
PRINT 'Ready to INSERT into MyTable ...';
INSERT INTO MyTable (x, SupplementalDividends)
VALUES (1, 3.2);
PRINT '**** CHANGES COMPLETE -- COMMITTING.';
COMMIT TRANSACTION;
Masalahnya adalah pesan kesalahan ketika saya menjalankan kode di atas:
Invalid column name 'SupplementalDividends'.
Mengapa ini menyebabkan kesalahan? Jika saya menambahkan kolom dalam kumpulan yang berbeda, di luar transaksi, itu akan berfungsi. Masalah saya adalah saya ingin menambahkan kolom dalam transaksi. Mengapa kesalahan?
sql-server
sql-server-2008-r2
t-sql
Tom Baxter
sumber
sumber
schema.ObjectName
. Awal yang baik untuk mengadaptasi praktik yang baik :-)Jawaban:
Hanya ingin mengklarifikasi bahwa ini adalah masalah pada saat run time, bukan waktu kompilasi, dan tidak ada hubungannya dengan fakta bahwa mereka berada dalam transaksi yang sama . Misalnya, mari kita asumsikan kita memiliki tabel ini:
Batch berikut mem-parsing berhasil (waktu kompilasi), tetapi saat runtime mendapat kesalahan yang Anda sebutkan dalam pertanyaan:
Di editor kueri di Management Studio, Anda dapat menyiasatinya dengan mudah, baik dengan:
Menempatkan pemisah batch di antara mereka, seperti:
Jika Anda menjalankan ini dari luar SQL Server (mis. Mengirim batch SQL dari kode aplikasi Anda), Anda dapat mengirim dua batch secara terpisah dengan cara yang sama, atau jika Anda benar-benar perlu mengirimkannya sebagai batch tunggal, Anda dapat gunakan SQL dinamis (seperti pada jawaban Gianluca ) untuk menunda resolusi nama.
sumber
Ini masalah yang mengikat. Kode terikat ke metadata tabel pada waktu kompilasi dan tidak terikat terlambat. Coba gunakan EXEC dan SQL dinamis untuk mengatasi batasan ini:
Pilihan lain adalah menggunakan prosedur tersimpan untuk memasukkan data: mengikat terlambat berlaku untuk prosedur tersimpan, tetapi tidak untuk permintaan ad-hoc. Sekali lagi, Anda harus menggunakan SQL dinamis untuk membuat prosedur, tetapi bisa membuatnya lebih mudah bagi Anda untuk melewati parameter:
Prosedur tersimpan sementara akan bekerja juga:
sumber
Saya ingin tahu mengapa Anda mengubah tabel dan memasukkan nilai ke dalam kolom itu dalam transaksi yang sama.
Hampir tidak ada kemungkinan bahwa Anda perlu mengubah tabel (dengan cara yang persis sama) lagi, kecuali jika dikembalikan setiap jam / hari, jadi mengapa melakukannya dalam transaksi?
Perubahan Anda belum dilakukan, dan karena itu tidak ditemukan ketika Anda mencoba memasukkannya.
Saran saya adalah untuk memisahkan tugas-tugas DDL dan DML Anda (setidaknya dalam transaksi yang terpisah pula).
sumber