2010-05-27 13 views
12

ऐसा लगता है कि एक्सेक्यूट स्ट्रिंग विधि के माध्यम से गतिशील एसक्यूएल का उपयोग करके बनाए गए #temptables एक अलग दायरे हैं और उसी संग्रहित प्रक्रिया में "निश्चित" एसक्यूएल द्वारा संदर्भित नहीं किया जा सकता है। हालांकि, मैं बाद में गतिशील एसक्यूएल में एक गतिशील एसक्यूएल कथन द्वारा बनाई गई एक टेम्प तालिका को संदर्भित कर सकता हूं लेकिन ऐसा लगता है कि एक संग्रहीत प्रक्रिया एक कॉलिंग क्लाइंट को क्वेरी परिणाम नहीं लौटाती जब तक कि SQL तय नहीं हो जाता।टी-एसक्यूएल डायनेमिक एसक्यूएल और टेम्प टेबल्स

एक साधारण 2 तालिका परिदृश्य: मेरे पास 2 टेबल हैं। आइए उन्हें ऑर्डर और आइटम कॉल करें। ऑर्डर में ऑर्डर आईडी की प्राथमिक कुंजी है और आइटम में आइटम आईडी की प्राथमिक कुंजी है। आइटम। ऑर्डर आईडी मूल आदेश की पहचान करने के लिए विदेशी कुंजी है। एक आदेश में 1 से एन आइटम हो सकते हैं।

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

आमतौर पर, मुझे लगता है कि अधिकांश लोग आइटम तालिका और अभिभावक ऑर्डर टेबल के बीच एक संयोजन बनाएंगे। मैं इसके बजाय 2 अलग-अलग प्रश्नों को निष्पादित करना चाहता हूं। सभी योग्यता प्राप्त करने वाले सभी आइटम वापस करने के लिए सभी योग्यता आइटम और दूसरे को वापस करने के लिए। कारण दो गुना है और आप सहमत हो सकते हैं या नहीं भी।

पहला कारण यह है कि मुझे मूल ऑर्डर तालिका में सभी कॉलम से पूछताछ करने की आवश्यकता है और यदि मैंने आइटम तालिका में ऑर्डर तालिका में शामिल होने के लिए एक ही प्रश्न किया है, तो मैं ऑर्डर जानकारी को कई बार दोहराता हूं। चूंकि आम तौर पर प्रति ऑर्डर की बड़ी संख्या में आइटम होते हैं, इसलिए मैं इससे बचना चाहता हूं क्योंकि इसके परिणामस्वरूप वसा ग्राहक को अधिक डेटा स्थानांतरित किया जा सकता है। इसके बजाए, जैसा कि बताया गया है, मैं डेटासेट में अलग-अलग दो टेबल वापस करना चाहता हूं और एक कस्टम ऑर्डर और चाइल्ड आइटम क्लाइंट ऑब्जेक्ट्स को पॉप्युलेट करने के लिए दो तालिकाओं का उपयोग करना चाहता हूं। (मुझे अभी तक LINQ या Entity Framework के बारे में पर्याप्त जानकारी नहीं है। मैं हाथ से अपनी वस्तुओं का निर्माण करता हूं)। दूसरा कारण है कि मैं एक के बजाय दो टेबल वापस करना चाहता हूं क्योंकि मेरे पास पहले से ही एक और प्रक्रिया है जो किसी ऑर्डर आईडी के लिए सभी ऑर्डर देता है, ऑर्डर के साथ और मैं उसी 2-टेबल दृष्टिकोण का उपयोग करना चाहता हूं ताकि मैं वापस लौटे 2 डेटाटेबल्स से मेरे कस्टम ऑर्डर और क्लाइंट ऑब्जेक्ट्स को पॉप्युलेट करने के लिए क्लाइंट कोड का पुन: उपयोग कर सकता है।

मैं ऐसा करने की उम्मीद कर रहा था क्या यह था:

ग्राहक के रूप में Winform पर बनाया कस्टम फ़िल्टर द्वारा निर्दिष्ट जो आइटम तालिका और प्रत्येक तालिका पर उपयुक्त फिल्टर करने के लिए आदेश तालिका संयोजन पर एक गतिशील एसक्यूएल स्ट्रिंग का निर्माण वसा-ग्राहक ऐप। ग्राहक पर एसक्यूएल निर्माण कुछ इस तरह देखा होगा:

TempSQL = " 

    INSERT INTO #ItemsToQuery 
     OrderId, ItemsId 
    FROM 
     Orders, Items 
    WHERE 
     Orders.OrderID = Items.OrderId AND 
     /* Some unpredictable Order filters go here */ 
     AND 
     /* Some unpredictable Items filters go here */ 
    " 

फिर, मैं एक संग्रहीत प्रक्रिया कहेंगे,

CREATE PROCEDURE GetItemsAndOrders(@tempSql as text) 
    Execute (@tempSQL) --to create the #ItemsToQuery table 

SELECT * FROM Items WHERE Items.ItemId IN (SELECT ItemId FROM #ItemsToQuery) 

SELECT * FROM Orders WHERE Orders.OrderId IN (SELECT DISTINCT OrderId FROM #ItemsToQuery) 

इस दृष्टिकोण के साथ समस्या यह है कि #ItemsToQuery तालिका है, क्योंकि यह था गतिशील एसक्यूएल द्वारा निर्मित, निम्नलिखित 2 स्थैतिक एसक्यूएल से पहुंच योग्य नहीं है और यदि मैं स्थैतिक एसक्यूएल को गतिशील में बदलता हूं, तो वसा क्लाइंट को कोई परिणाम वापस नहीं भेजा जाता है।

3 चारों ओर मन के लिए आते हैं, लेकिन मैं एक बेहतर एक के लिए देखो कर रहा हूँ:

1) पहली एसक्यूएल ग्राहक से गतिशील रूप से निर्माण किया एसक्यूएल को क्रियान्वित करते हुए प्रदर्शन किया जा सकता है। इसके बाद परिणाम उपरोक्त संग्रहीत प्रक्रिया के एक संशोधित संस्करण में एक तालिका के रूप में पारित किया जा सकता है। मैं एक्सएमएल के रूप में टेबल डेटा पास करने से परिचित हूं। अगर मैंने ऐसा किया, तो संग्रहित प्रो डेटा को स्थिर एसक्यूएल का उपयोग करके एक अस्थायी तालिका में डाल सकता है, क्योंकि यह गतिशील एसक्यूएल द्वारा बनाया गया था, फिर बिना किसी समस्या के पूछताछ की जा सकती है।(मैं एक्सएमएल के बजाय नए टेबल टाइप परम को पार करने में भी जांच कर सकता हूं।) हालांकि, मैं संग्रहित प्रक्रिया में संभावित रूप से बड़ी सूचियों को पार करने से बचना चाहता हूं।

2) मैं ग्राहक से सभी प्रश्नों को निष्पादित कर सकता हूं।

SELECT Items.* FROM Orders, Items WHERE Order.OrderId = Items.OrderId AND (dynamic filter) 
SELECT Orders.* FROM Orders, Items WHERE Order.OrderId = Items.OrderId AND (dynamic filter) 

यह अभी भी मुझे मेरे मुवक्किल पक्षीय वस्तु आबादी कोड पुन: उपयोग करने क्योंकि आदेश और आइटम दो अलग-अलग तालिकाओं में लौटा दी करने के लिए जारी की क्षमता के साथ प्रदान करता है:

पहले कुछ इस तरह होगा।

मुझे यह महसूस हो रहा है कि मेरे पास मेरे संग्रहित प्रो में टेबल डेटा प्रकार का उपयोग करके कुछ विकल्प हो सकते हैं, लेकिन यह मेरे लिए भी नया है और मैं उस पर थोड़ा सा चम्मच खाने की सराहना करता हूं।

यदि आपने जो भी लिखा है, उसमें आपने इसे स्कैन भी किया है, तो मुझे हैरान है, लेकिन यदि ऐसा है, तो मैं इस सर्वोत्तम विचार को पूरा करने के बारे में आपके किसी भी विचार को डरता हूं।

+0

टीएलडीआर: http://www.urbandictionary.com/define.php?term=TLDR –

उत्तर

17

आप इसे गतिशील एसक्यूएल में उपलब्ध हो जाएगा अपनी मेज पहले तो बनाने की जरूरत

इस

create table #temp3 (id int) 
exec ('insert #temp3 values(1)') 

select * from #temp3 

काम करता है इस

exec ('create table #temp2 (id int) 
    insert #temp2 values(1)') 

select * from #temp2 

काम नहीं करेगा दूसरे शब्दों में:

  1. अस्थायी तालिका बनाने

  2. proc निष्पादित

  3. अस्थायी तालिका

यहाँ से

का चयन पूरा उदाहरण गतिशील एसक्यूएल से

create proc prTest2 @var varchar(100) 
as 
exec (@var) 
go 

create table #temp (id int) 

exec prTest2 'insert #temp values(1)' 

select * from #temp 
+0

मुझे लगता है कि यह भी काम करता है: #temptable exec ('select ?? से ??') में डालें; –

+4

समस्या तब होती है जब हम कॉलम परिभाषा नहीं जानते हैं, तब के बारे में कैसे? – Muflix

0

परिणाम सेट ग्राहक को लौट रहे हैं। मैंने यह बहुत कुछ किया है।

आप अस्थायी तालिकाओं और चर के माध्यम से डेटा साझा करने और एसक्यूएल और गतिशील एसक्यूएल के बीच जैसी चीजों को साझा करने के साथ मुद्दों के बारे में सही हैं।

मैं अपने अस्थायी तालिका काम कर प्राप्त करने की कोशिश में लगता है, तो आप शायद मिल गया है कुछ चीजें हैं, उलझन में है क्योंकि आप निश्चित रूप से से एक सपा जो गतिशील एसक्यूएल निष्पादित करता है डेटा प्राप्त कर सकते हैं:

USE SandBox 
GO 

CREATE PROCEDURE usp_DynTest(@table_type AS VARCHAR(255)) 
AS 
BEGIN 
    DECLARE @sql AS VARCHAR(MAX) = 'SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = ''' + @table_type + '''' 
    EXEC (@sql) 
END 
GO 

EXEC usp_DynTest 'BASE TABLE' 
GO 

EXEC usp_DynTest 'VIEW' 
GO 

DROP PROCEDURE usp_DynTest 
GO 

इसके अलावा:

USE SandBox 
GO 

CREATE PROCEDURE usp_DynTest(@table_type AS VARCHAR(255)) 
AS 
BEGIN 
    DECLARE @sql AS VARCHAR(MAX) = 'SELECT * INTO #temp FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = ''' + @table_type + '''; SELECT * FROM #temp;' 
    EXEC (@sql) 
END 
GO 

EXEC usp_DynTest 'BASE TABLE' 
GO 

EXEC usp_DynTest 'VIEW' 
GO 

DROP PROCEDURE usp_DynTest 
GO 
+0

यदि आप proc में temp तालिका बनाते हैं तो यह काम नहीं करेगा, आपको पहले temp तालिका बनाना होगा, फिर आप इसे proc.see में भी बना सकते हैं। मेरा उदाहरण – SQLMenace

+0

@SQLMenace - मैं देख रहा हूं कि आप क्या कह रहे हैं। मेरा मुद्दा यह था कि आप गतिशील एसक्यूएल से सेट वापस कर सकते हैं (और वे अपनी खुद की अस्थायी तालिकाओं का उपयोग कर सकते हैं और उनसे वापस आ सकते हैं)। मैं एक दूसरा उदाहरण जोड़ूंगा। –

2

मैं दृढ़ता से सुझाव है कि आप मुझे एक अल्पविराम सीमांकित पाठ सूची में उत्तीर्ण होने की दृष्टिकोण की तरह के माध्यम से http://www.sommarskog.se/arrays-in-sql-2005.html

व्यक्तिगत रूप से पढ़ने के लिए है, तो pars इसे टेबल फ़ंक्शन में टेक्स्ट के साथ दर्ज करना और इसमें शामिल होना। यदि आप पहले कनेक्शन में इसे बनाते हैं तो अस्थायी तालिका दृष्टिकोण काम कर सकता है। लेकिन यह थोड़ा गड़बड़ महसूस करता है।

+1

मैं जल्द ही सीएसवी से एक्सएमएल पास कर दूंगा। हालांकि अधिक वर्बोज़, यह अतिरिक्त कॉलम को संशोधित करने और पास करने के लिए लचीलापन की अनुमति देता है। और एसक्यूएल पहले ही जानता है कि XML को कैसे पार्स करना है। लेकिन मैंने क्लाइंट डेटासेट को सर्वर साइड टेबल वैरिएबल में पास करने के लिए उदाहरण देखा। बहुत साफ। यहां तक ​​कि हालांकि, अस्थायी तालिका IMHO से कम वांछनीय है जो एक दृष्टिकोण है जो स्केल करने की संभावना कम है। – ChadD

3
DECLARE @DynamicQuery NVarchar(MAX) 
    Set @DynamicQuery='Select * into #temp from (select * from tablename) alias 
    select * from #temp 
    drop table #temp' 
    exec sp_executesql @DynamicQuery 

या दूसरा तरीका।
यह काम करेगा। लेकिन आपको वैश्विक चर की अतिरिक्त देखभाल करने की आवश्यकता है।

IF OBJECT_ID('tempdb..##temp2') IS NULL 
BEGIN 
    exec ('create table ##temp2 (id int) 
     insert ##temp2 values(1)') 

    select * from ##temp2 

END 

आपका उद्देश्य प्राप्त होने के बाद मैन्युअल रूप से ## temp2 ऑब्जेक्ट को मिटाना न भूलें।

IF OBJECT_ID('tempdb..##temp2') IS NOT NULL 
DROP Table ##temp2 

नोट: न इस विधि का उपयोग करता है, तो आप न डेटाबेस पर पूर्ण संरचना पता है।

संबंधित मुद्दे