Bagaimana caranya SELECT * INTO [temp table] FROM [stored procedure]
? Tidak FROM [Table]
dan tanpa mendefinisikan [temp table]
?
Select
semua data dari BusinessLine
dalam tmpBusLine
bekerja dengan baik.
select *
into tmpBusLine
from BusinessLine
Saya mencoba yang sama, tetapi menggunakan stored procedure
yang mengembalikan data, tidak persis sama.
select *
into tmpBusLine
from
exec getBusinessLineHistory '16 Mar 2009'
Pesan keluaran:
Msg 156, Level 15, Status 1, Baris 2 Sintaks salah di dekat kata kunci 'exec'.
Saya telah membaca beberapa contoh membuat tabel sementara dengan struktur yang sama dengan prosedur tersimpan tersimpan, yang berfungsi dengan baik, tetapi alangkah baiknya jika tidak menyediakan kolom apa pun.
Jawaban:
Anda dapat menggunakan OPENROWSET untuk ini. Silahkan lihat. Saya juga menyertakan kode sp_configure untuk mengaktifkan Kueri Terdistribusi Ad Hoc, jika belum diaktifkan.
sumber
Jika Anda ingin melakukannya tanpa terlebih dahulu mendeklarasikan tabel sementara, Anda bisa mencoba membuat fungsi yang ditentukan pengguna daripada prosedur yang disimpan dan membuat fungsi yang ditentukan pengguna mengembalikan tabel. Atau, jika Anda ingin menggunakan prosedur tersimpan, coba sesuatu seperti ini:
sumber
Di SQL Server 2005 Anda bisa menggunakan
INSERT INTO ... EXEC
untuk memasukkan hasil dari prosedur tersimpan ke dalam tabel. Dari dokumentasi MSDNINSERT
(untuk SQL Server 2000, sebenarnya):sumber
Ini adalah jawaban untuk versi pertanyaan Anda yang sedikit dimodifikasi. Jika Anda dapat mengabaikan penggunaan prosedur tersimpan untuk fungsi yang ditentukan pengguna, Anda dapat menggunakan fungsi yang ditentukan pengguna yang ditentukan tabel inline. Ini pada dasarnya adalah prosedur tersimpan (akan mengambil parameter) yang mengembalikan tabel sebagai hasil yang ditetapkan; dan karena itu akan cocok dengan pernyataan INTO.
Berikut ini adalah artikel cepat yang bagus dan fungsi-fungsi yang ditentukan pengguna lainnya. Jika Anda masih memiliki kebutuhan mengemudi untuk prosedur tersimpan, Anda bisa membungkus fungsi yang ditentukan pengguna dengan nilai tabel inline dengan prosedur tersimpan. Prosedur tersimpan hanya melewati parameter ketika ia memanggil pilih * dari fungsi yang ditentukan pengguna yang ditentukan tabel inline.
Jadi misalnya, Anda akan memiliki fungsi yang ditentukan pengguna dengan nilai tabel inline untuk mendapatkan daftar pelanggan untuk wilayah tertentu:
Anda kemudian dapat memanggil fungsi ini untuk mendapatkan hasil seperti apa:
Atau untuk melakukan SELECT INTO:
Jika Anda masih membutuhkan prosedur tersimpan, maka bungkus fungsinya seperti ini:
Saya pikir ini adalah metode yang paling 'hack-less' untuk mendapatkan hasil yang diinginkan. Ini menggunakan fitur yang ada karena mereka dimaksudkan untuk digunakan tanpa komplikasi tambahan. Dengan menumpuk fungsi yang ditentukan pengguna yang dinilai tabel inline dalam prosedur tersimpan, Anda memiliki akses ke fungsionalitas dalam dua cara. Plus! Anda hanya memiliki satu titik pemeliharaan untuk kode SQL yang sebenarnya.
Penggunaan OPENROWSET telah disarankan, tetapi ini bukan tujuan dari fungsi OPENROWSET untuk digunakan (Dari Buku Daring):
Menggunakan OPENROWSET akan menyelesaikan pekerjaan, tetapi itu akan menimbulkan beberapa biaya tambahan untuk membuka koneksi lokal dan menyusun data. Ini juga mungkin tidak menjadi pilihan dalam semua kasus karena memerlukan izin permintaan ad hoc yang menimbulkan risiko keamanan dan karenanya mungkin tidak diinginkan. Juga, pendekatan OPENROWSET akan menghalangi penggunaan prosedur tersimpan yang mengembalikan lebih dari satu set hasil. Membungkus beberapa inline table-nilai fungsi yang ditentukan pengguna dalam satu prosedur tersimpan dapat mencapai ini.
sumber
sumber
Jika Anda tidak mengetahui skema tersebut maka Anda dapat melakukan hal berikut. Harap dicatat bahwa ada risiko keamanan yang parah dalam metode ini.
sumber
Ketika prosedur tersimpan mengembalikan banyak kolom dan Anda tidak ingin secara manual "membuat" tabel sementara untuk menampung hasilnya, saya telah menemukan cara termudah untuk masuk ke prosedur tersimpan dan menambahkan "menjadi" klausa pada pernyataan pilih terakhir dan tambahkan 1 = 0 ke klausa di mana.
Jalankan prosedur tersimpan sekali dan kembali dan menghapus kode SQL yang baru saja Anda tambahkan. Sekarang, Anda akan memiliki tabel kosong yang cocok dengan hasil prosedur tersimpan. Anda bisa "skrip tabel sebagai buat" untuk tabel sementara atau cukup masukkan langsung ke tabel itu.
sumber
SELECT INTO
tabel temp dan melakukan tabel skrip sebagai buat dari tabel temp? Tabel temp muncultempdb
tetapi saya tidak dapat melakukan klik kanan dan membuat skrip buat. Bantuan apa pun dihargai.select ... into new_table
secara implisit membuat tabel aktual.declare @s varchar(max)='';select @s=@s+','+COLUMN_NAME+' '+DATA_TYPE+isnull('('+case CHARACTER_MAXIMUM_LENGTH when -1 then 'max' else cast(CHARACTER_MAXIMUM_LENGTH as varchar(10))end+')','')from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='...';select @s
sumber
Apakah prosedur tersimpan Anda hanya mengambil data atau memodifikasinya juga? Jika hanya digunakan untuk mengambil, Anda dapat mengubah prosedur tersimpan menjadi fungsi dan menggunakan Common Table Expressions (CTEs) tanpa harus menyatakannya, sebagai berikut:
Namun, apa pun yang perlu diambil dari CTE harus digunakan dalam satu pernyataan saja. Anda tidak dapat melakukan
with temp as ...
dan mencoba menggunakannya setelah beberapa baris SQL. Anda dapat memiliki beberapa CTE dalam satu pernyataan untuk kueri yang lebih kompleks.Sebagai contoh,
sumber
Jika tabel hasil proc yang disimpan terlalu rumit untuk mengetikkan pernyataan "buat tabel" dengan tangan, dan Anda tidak bisa menggunakan OPENQUERY ATAU OPENROWSET, Anda bisa menggunakan sp_help untuk membuat daftar kolom dan tipe data untuk Anda. Setelah Anda memiliki daftar kolom, tinggal memformatnya sesuai dengan kebutuhan Anda.
Langkah 1: Tambahkan "ke #temp" ke kueri keluaran (mis. "Pilih [...] ke #temp dari [...]").
Cara termudah adalah mengedit kueri keluaran di proc secara langsung. jika Anda tidak dapat mengubah proc yang disimpan, Anda dapat menyalin konten ke jendela permintaan baru dan memodifikasi permintaan di sana.
Langkah 2: Jalankan sp_help di tabel temp. (mis. "exec tempdb..sp_help #temp")
Setelah membuat tabel temp, jalankan sp_help di tabel temp untuk mendapatkan daftar kolom dan tipe data termasuk ukuran bidang varchar.
Langkah 3: Salin kolom & tipe data ke dalam pernyataan tabel buat
Saya memiliki lembar Excel yang saya gunakan untuk memformat output sp_help menjadi pernyataan "buat tabel". Anda tidak perlu sesuatu yang mewah, cukup salin dan tempel ke editor SQL Anda. Gunakan nama kolom, ukuran, dan jenis untuk membangun pernyataan "Buat tabel #x [...]" atau "nyatakan @x tabel [...]" yang dapat Anda gunakan untuk menyisipkan hasil dari prosedur tersimpan.
Langkah 4: Masukkan ke dalam tabel yang baru dibuat
Sekarang Anda akan memiliki kueri yang seperti solusi lain yang dijelaskan di utas ini.
Teknik ini juga dapat digunakan untuk mengonversi tabel temp (
#temp
) ke variabel tabel (@temp
). Meskipun ini mungkin lebih banyak langkah daripada hanya menuliscreate table
pernyataan sendiri, itu mencegah kesalahan manual seperti kesalahan ketik dan tipe data dalam proses besar. Mendebug kesalahan ketik bisa memakan waktu lebih lama daripada menulis kueri di tempat pertama.sumber
Jika OPENROWSET menyebabkan Anda mengalami masalah, ada cara lain mulai 2012 dan seterusnya; memanfaatkan sys.dm_exec_describe_first_result_set_for_object, seperti yang disebutkan di sini: Ambil nama kolom dan jenis prosedur tersimpan?
Pertama, buat prosedur tersimpan ini untuk menghasilkan SQL untuk tabel sementara:
Untuk menggunakan prosedur, panggil dengan cara berikut:
Perhatikan bahwa saya menggunakan tabel sementara global. Itu karena menggunakan EXEC untuk menjalankan SQL dinamis membuat sesi sendiri, sehingga tabel sementara biasa akan berada di luar jangkauan ke kode berikutnya. Jika tabel sementara global adalah masalah, Anda bisa menggunakan tabel sementara biasa, tetapi setiap SQL berikutnya harus dinamis, yaitu, juga dieksekusi oleh pernyataan EXEC.
sumber
@SQL
.Quassnoi menempatkan saya hampir di sana, tetapi satu hal hilang:
**** Saya perlu menggunakan parameter dalam prosedur tersimpan. ****
Dan OPENQUERY tidak mengizinkan ini terjadi:
Jadi saya menemukan cara untuk bekerja sistem dan juga tidak harus membuat definisi tabel begitu kaku, dan mendefinisikannya kembali di dalam prosedur lain yang tersimpan (dan tentu saja mengambil kesempatan itu mungkin rusak)!
Ya, Anda dapat secara dinamis membuat definisi tabel yang dikembalikan dari prosedur tersimpan dengan menggunakan pernyataan OPENQUERY dengan variabel palsu (selama NO SET HASIL mengembalikan jumlah bidang yang sama dan dalam posisi yang sama dengan dataset dengan data yang baik).
Setelah tabel dibuat, Anda dapat menggunakan prosedur tersimpan exec ke dalam tabel sementara sepanjang hari.
Dan untuk dicatat (seperti yang ditunjukkan di atas) Anda harus mengaktifkan akses data,
Kode:
Terima kasih atas informasi yang disediakan semula ... Ya, akhirnya saya tidak harus membuat semua definisi tabel palsu (ketat) ini ketika menggunakan data dari prosedur atau basis data lain yang tersimpan, dan ya Anda dapat menggunakan parameter juga.
Cari tag referensi:
SQL 2005 menyimpan prosedur ke dalam tabel temp
openquery dengan prosedur tersimpan dan variabel 2005
openquery dengan variabel
jalankan prosedur tersimpan ke dalam tabel temp
Pembaruan: ini tidak akan berfungsi dengan tabel sementara jadi saya harus menggunakan secara manual membuat tabel sementara.
Pemberitahuan gelandangan : ini tidak akan berfungsi dengan tabel sementara , http://www.sommarskog.se/share_data.html#OPENQUERY
Referensi: Hal berikutnya adalah mendefinisikan LOCALSERVER. Ini mungkin terlihat seperti kata kunci dalam contoh, tetapi sebenarnya hanya nama. Inilah cara Anda melakukannya:
Untuk membuat server yang ditautkan, Anda harus memiliki izin ALTER ANY SERVER, atau menjadi anggota dari salah satu peran server tetap sysadmin atau setupadmin.
OPENQUERY membuka koneksi baru ke SQL Server. Ini memiliki beberapa implikasi:
Prosedur yang Anda panggil dengan OPENQUERY tidak dapat merujuk tabel sementara yang dibuat dalam koneksi saat ini.
Koneksi baru memiliki database default sendiri (didefinisikan dengan sp_addlinkedserver, default adalah master), jadi semua spesifikasi objek harus menyertakan nama database.
Jika Anda memiliki transaksi terbuka dan menahan kunci saat Anda menelepon OPENQUERY, prosedur yang dipanggil tidak dapat mengakses apa yang Anda kunci. Artinya, jika Anda tidak hati-hati Anda akan memblokir diri sendiri.
Menghubungkan tidak gratis, jadi ada penalti kinerja.
sumber
SELECT @@SERVERNAME
. Anda juga dapat menggunakanEXEC sp_serveroption @@SERVERNAME, 'DATA ACCESS', TRUE
Jika Anda cukup beruntung memiliki SQL 2012 atau lebih tinggi, Anda dapat menggunakannya
dm_exec_describe_first_result_set_for_object
Saya baru saja mengedit sql yang disediakan oleh gotqn. Terima kasih, terima kasih.
Ini menciptakan tabel temp global dengan nama yang sama dengan nama prosedur. Tabel temp nantinya dapat digunakan sesuai kebutuhan. Hanya saja, jangan lupa untuk menjatuhkannya sebelum menjalankan ulang.
sumber
sys.all_objects
alih-alihsys.procedures
jika Anda ingin melakukan ini untuk prosedur tersimpan bawaan.Proc yang tersimpan ini berfungsi:
Ini sedikit pengerjaan ulang ini: Masukkan hasil prosedur tersimpan ke dalam tabel sehingga benar-benar berfungsi.
Jika Anda ingin bekerja dengan tabel sementara maka Anda harus menggunakan
##GLOBAL
tabel dan menjatuhkannya setelah itu.sumber
Untuk memasukkan set rekaman pertama dari prosedur tersimpan ke dalam tabel sementara Anda harus mengetahui yang berikut:
sp_executesql
)Di atas mungkin terlihat sebagai batasan, tetapi IMHO itu masuk akal - jika Anda menggunakan
sp_executesql
Anda dapat sekali saja mengembalikan dua kolom dan sepuluh, dan jika Anda memiliki beberapa set hasil, Anda tidak dapat memasukkannya ke dalam beberapa tabel juga - Anda dapat memasukkan maksimum dalam dua tabel dalam satu pernyataan T-SQL (menggunakanOUTPUT
klausa dan tidak ada pemicu).Jadi, masalah utamanya adalah bagaimana mendefinisikan struktur tabel sementara sebelum melakukan
EXEC ... INTO ...
pernyataan.Yang pertama berfungsi dengan
OBJECT_ID
sedangkan yang kedua dan ketiga bekerja dengan permintaan Ad-hoc juga. Saya lebih suka menggunakan DMV daripada sp karena Anda dapat menggunakanCROSS APPLY
dan membangun definisi tabel sementara untuk beberapa prosedur secara bersamaan.Juga, perhatikan
system_type_name
bidang karena ini bisa sangat berguna. Ini menyimpan definisi lengkap kolom. Sebagai contoh:dan Anda dapat menggunakannya secara langsung di sebagian besar kasus untuk membuat definisi tabel.
Jadi, saya pikir dalam sebagian besar kasus (jika prosedur tersimpan sesuai dengan kriteria tertentu), Anda dapat dengan mudah membuat pernyataan dinamis untuk menyelesaikan masalah tersebut (buat tabel sementara, masukkan hasil prosedur tersimpan di dalamnya, lakukan apa yang Anda perlukan dengan data) .
Perhatikan, bahwa objek di atas gagal untuk menentukan data set hasil pertama dalam beberapa kasus seperti ketika pernyataan T-SQL dinamis dieksekusi atau tabel sementara digunakan dalam prosedur tersimpan.
sumber
Sekarang saya tahu apa hasil dari prosedur saya, jadi saya melakukan permintaan berikut.
NILAI (10, 5, 1, NULL) SET IDENTITY_INSERT [dbo]. [TblTestingTree] Aktif
sumber
Jika kueri tidak berisi parameter, gunakan yang
OpenQuery
lain gunakanOpenRowset
.Hal dasar adalah membuat skema sesuai prosedur yang tersimpan dan memasukkan ke dalam tabel itu. misalnya:
sumber
Kode
Saya harap ini membantu. Harap memenuhi syarat yang sesuai.
sumber
Saya menemukan Passing Arrays / DataTables ke dalam Stored Procedures yang mungkin memberi Anda ide lain tentang bagaimana Anda bisa menyelesaikan masalah Anda.
Tautan menyarankan untuk menggunakan parameter tipe gambar untuk masuk ke prosedur tersimpan. Kemudian dalam prosedur tersimpan, gambar diubah menjadi tabel variabel yang berisi data asli.
Mungkin ada cara ini bisa digunakan dengan tabel sementara.
sumber
Saya menemui masalah yang sama dan inilah yang saya lakukan untuk ini dari saran Paul . Bagian utama di sini adalah untuk digunakan
NEWID()
untuk menghindari beberapa pengguna menjalankan prosedur toko / skrip pada saat yang sama, rasa sakit untuk tabel sementara global.sumber
Metode lain adalah membuat tipe dan menggunakan PIPELINED untuk kemudian mengirimkan kembali objek Anda. Namun ini terbatas untuk mengetahui kolom. Tetapi ia memiliki keuntungan untuk bisa melakukan:
sumber
Ini adalah proses 2 langkah sederhana: - membuat tabel sementara - Masukkan ke dalam tabel sementara.
Kode untuk melakukan hal yang sama:
sumber
Setelah mencari di sekitar saya menemukan cara untuk membuat tabel temp secara dinamis untuk setiap prosedur tersimpan tanpa menggunakan
OPENROWSET
atauOPENQUERY
menggunakan skema umum definisi hasil Stored Procedure terutama ketika Anda bukan Administrator basis data.Sql server memiliki buit-in proc
sp_describe_first_result_set
yang dapat memberi Anda skema dari setiap prosedur resultset. Saya membuat tabel skema dari hasil prosedur ini dan secara manual mengatur semua bidang ke NULLABLE.Anda bisa mengubah skema untuk versi SQL server yang Anda gunakan (jika perlu).
sumber
Jika Anda tahu parameter yang dilewati dan jika Anda tidak memiliki akses untuk membuat sp_configure, maka edit prosedur tersimpan dengan parameter ini dan hal yang sama dapat disimpan dalam tabel global ##.
sumber
Ini dapat dilakukan dalam SQL Server 2014+ asalkan prosedur tersimpan hanya mengembalikan satu tabel. Jika ada yang menemukan cara melakukan ini untuk beberapa tabel saya ingin tahu tentang hal itu.
Ini menarik definisi tabel yang dikembalikan dari tabel sistem, dan menggunakannya untuk membangun tabel temp untuk Anda. Anda kemudian dapat mengisinya dari prosedur tersimpan seperti yang dinyatakan sebelumnya.
Ada juga varian ini yang bekerja dengan Dynamic SQL juga.
sumber
Beberapa tahun terlambat untuk pertanyaan, tetapi saya membutuhkan sesuatu seperti ini untuk beberapa generasi kode yang cepat dan kotor. Saya percaya karena orang lain telah menyatakan bahwa hanya lebih mudah untuk mendefinisikan tabel temp di muka, tetapi metode ini harus bekerja untuk kueri prosedur tersimpan sederhana atau statemen sql.
Ini akan sedikit berbelit-belit, tetapi meminjam dari kontributor di sini serta solusi Paul White dari DBA Stack Exchange Dapatkan disimpan-hasil jenis kolom prosedur . Sekali lagi, untuk mengulangi pendekatan ini & contoh tidak dirancang untuk proses dalam lingkungan multi-pengguna. Dalam hal ini definisi tabel sedang diatur untuk waktu yang singkat di tabel temp global untuk referensi oleh proses templat pembuatan kode.
Saya belum sepenuhnya menguji ini sehingga mungkin ada peringatan sehingga Anda mungkin ingin pergi ke tautan MSDN dalam jawaban Paul White. Ini berlaku untuk SQL 2012 dan lebih tinggi.
Pertama-tama gunakan prosedur tersimpan sp_describe_first_result_set yang menyerupai uraian Oracle.
Ini akan mengevaluasi baris pertama dari hasil pertama yang ditetapkan sehingga jika prosedur atau pernyataan Anda yang disimpan mengembalikan beberapa kueri, itu hanya akan menggambarkan hasil pertama.
Saya membuat proc tersimpan untuk memecah tugas-tugas yang mengembalikan satu bidang untuk memilih dari untuk membuat definisi tabel temp.
Masalahnya adalah Anda perlu menggunakan tabel global, tetapi Anda harus membuatnya cukup unik sehingga Anda bisa sering menjatuhkan dan membuatnya dari sana tanpa khawatir akan tabrakan.
Dalam contoh saya menggunakan Guid (FE264BF5_9C32_438F_8462_8A5DC8DEE49E) untuk variabel global yang mengganti tanda hubung dengan garis bawah
Sekali lagi, saya hanya mengujinya dengan kueri prosedur tersimpan sederhana dan kueri sederhana sehingga jarak tempuh Anda dapat bervariasi. Semoga ini bisa membantu seseorang.
sumber
Yah, Anda harus membuat tabel temp, tetapi tidak harus memiliki skema yang tepat .... Saya telah membuat prosedur tersimpan yang memodifikasi tabel temp yang ada sehingga memiliki kolom yang diperlukan dengan data yang benar ketik dan ketertiban (menjatuhkan semua kolom yang ada, menambahkan kolom baru):
Catatan ini tidak akan berfungsi jika sys.dm_exec_describe_first_result_set_for_object tidak dapat menentukan hasil dari prosedur tersimpan (misalnya jika menggunakan tabel temp).
sumber
Jika Anda membiarkan SQL dinamis membuat tabel temp, tabel ini dimiliki oleh koneksi SQL Dinamis, sebagai lawan dari koneksi prosedur tersimpan Anda dipanggil dari.
Msg 208, Level 16, Negara 0 Nama objek tidak valid '#Pivoted'. Ini karena #Pivoted dimiliki oleh koneksi SQL Dinamis. Jadi instruksi terakhir
gagal
Salah satu cara untuk tidak menghadapi masalah ini adalah memastikan semua referensi ke #Pivoted dibuat dari dalam kueri dinamis itu sendiri:
sumber
Saya akan melakukan hal berikut
Buat (konversi SP ke) UDF (Nilai tabel UDF).
select * into #tmpBusLine from dbo.UDF_getBusinessLineHistory '16 Mar 2009'
sumber