2012-05-24 11 views
5

क्या संग्रहीत प्रक्रिया में इनपुट पैरामीटर के रूप में टेबल नाम को पास करना संभव है?एसक्यूएल संग्रहीत प्रक्रिया में तालिका का नाम पास करना

उदाहरण के लिए:

create procedure test 
@tablename char(10) 
as 
begin 
select * from @tablename 
end 
go 

मैं जानता हूँ कि यह काम नहीं करता। तो अगर मैं टेबल नाम को संग्रहित प्रक्रिया में पास करना चाहता हूं तो सबसे अच्छा तरीका क्या है?

बहुत धन्यवाद

उत्तर

10

यह करने के लिए सबसे सुरक्षित तरीका एक दृश्य के माध्यम से है।

एक दृश्य बनाएं जो यूनियन उन सभी तालिकाओं को बनाते हैं जिन्हें आप एक्सेस करना चाहते हैं (और सभी के पास समान कॉलम संरचना होनी चाहिए), और तालिका नाम के साथ पंक्तियों को उपसर्ग करें।

CREATE VIEW MultiTable 
AS 
    SELECT 'table1' AS TableName, * FROM table1 
    UNION ALL 
    SELECT 'table2' AS TableName, * FROM table2 
    UNION ALL 
    SELECT 'table3' AS TableName, * FROM table3 

आपका संगृहीत प्रक्रिया अब तालिका नाम पर फ़िल्टर कर सकते हैं:

CREATE PROCEDURE test 
    @TableName varchar(100) 
AS 
    SELECT * FROM MultiTable WHERE TableName = @TableName 

इस गतिशील एसक्यूएल निर्माण और निष्पादन का उपयोग करके अधिक सुरक्षित है।

+0

बहुत बहुत धन्यवाद। – gunnerz

+1

यह ध्यान दिया जाना चाहिए कि, "*" का उपयोग करके, उदाहरण यह मान रहा है कि सभी तीन तालिकाओं में समान कॉलम हैं। मुझे विश्वास है कि आपको अन्यथा एक त्रुटि मिलेगी। यहां तक ​​कि यदि यह मामला था, तो सर्वोत्तम अभ्यास के रूप में आपको शायद प्रत्येक चयन में उन्हें गणना करना चाहिए। – Buggieboy

+0

@Buggieboy शायद उस त्रुटि को प्राप्त कर रहा है यदि स्तंभों में से केवल एक तालिका में परिवर्तन बदलते हैं ........ –

3

आपको गतिशील एसक्यूएल का उपयोग करने की आवश्यकता होगी, लेकिन आपको संभावित एसक्यूएल इंजेक्शन जोखिमों के बारे में जागरूक होने की आवश्यकता है, जैसे कि आप अपने आप को खोलते हैं जैसे @tablename में कुछ डोडी है, आप दर्द की दुनिया में समाप्त हो सकते हैं।

उदा

-- basic check to see if a table with this name exists 
IF NOT EXISTS(SELECT * FROM sys.tables WHERE name = @tablename) 
    RETURN 

DECLARE @sql NVARCHAR(100) 
SET @sql = 'SELECT * FROM ' + QUOTENAME(@tablename) 
EXECUTE(@sql) 

आपको इस दृष्टिकोण से बहुत सावधान रहना होगा, सुनिश्चित करें कि आप सुरक्षा कीड़े का एक खोल नहीं खोलें।

मेरी दूसरी चिंता यह है कि आप जेनेरिक डेटा एक्सेस स्पॉक्स बनाने की कोशिश कर रहे हैं जो आमतौर पर एक बुरा विचार है। जाहिर है, मैं आपके उपयोग के मामले को नहीं जानता।

+1

[आपका केस नंबर एक है!] (Http://www.sommarskog.se/dynamic_sql। एचटीएमएल # Common_cases) – Bridge

+0

बहुत बहुत धन्यवाद। एसक्यूएल इंजेक्शन का लगभग नगण्य मौका है क्योंकि टेबल नाम के लिए कोई उपयोगकर्ता प्रविष्टि नहीं है। इसका उपयोग केवल आंतरिक रूप से अनुप्रयोग द्वारा किया जाता है - और मैं अलग-अलग तालिका नामों को छोड़कर एक ही तर्क के साथ एकाधिक संग्रहीत prcs बनाने से बचना चाहता हूं – gunnerz

+1

@ ब्रिज - हाँ, मैं पूरी तरह से सहमत हूं। जिन मामलों में मुझे वास्तव में एक गतिशील तालिका नाम का उपयोग करने की आवश्यकता है, मैंने व्यक्तिगत रूप से एसक्यूएल को एप्लिकेशन कोड में जेनरेट किया है। लेकिन अक्सर मुझे वास्तविक उपयोग केस – AdaTheDev

2
DECLARE @Name VARCHAR(50) 
SET @Name='Company' 

EXEC('SELECT * from ' + @Name) 

उपयोग इस तरह से डेटाबेस से रिकॉर्ड प्राप्त करने के लिए।