टी-एसक्यूएल में एक टेबल चर का चयन करें


372

एक जटिल चयन क्वेरी मिला, जिसमें से मैं सभी पंक्तियों को एक तालिका चर में सम्मिलित करना चाहूंगा, लेकिन टी-एसक्यूएल इसकी अनुमति नहीं देता है।

उसी पंक्तियों के साथ, आप SELO INTO या INSERT EXEC क्वेरीज़ के साथ तालिका चर का उपयोग नहीं कर सकते। http://odetocode.com/Articles/365.aspx

संक्षिप्त उदाहरण:

declare @userData TABLE(
                        name varchar(30) NOT NULL,
                        oldlocation varchar(30) NOT NULL
                       )

SELECT name, location
INTO @userData
FROM myTable
    INNER JOIN otherTable ON ...
WHERE age > 30

तालिका चर में डेटा का उपयोग बाद में इसे अलग-अलग तालिकाओं में सम्मिलित करने / अपडेट करने के लिए किया जाएगा (ज्यादातर मामूली अपडेट के साथ समान डेटा की प्रतिलिपि)। इसका लक्ष्य केवल स्क्रिप्ट को थोड़ा और पठनीय बनाना होगा और SELECT INTOसीधे तालिकाओं में सीधे करने की तुलना में अधिक आसानी से अनुकूलन योग्य होगा। प्रदर्शन कोई समस्या नहीं है, क्योंकि rowcountयह काफी छोटा है और यह केवल जरूरत पड़ने पर मैन्युअल रूप से चलता है।
... या मुझे बताएं कि क्या मैं यह सब गलत कर रहा हूं।

जवाबों:


601

कुछ इस तरह की कोशिश करो:

DECLARE @userData TABLE(
    name varchar(30) NOT NULL,
    oldlocation varchar(30) NOT NULL
);

INSERT INTO @userData (name, oldlocation)
SELECT name, location FROM myTable
INNER JOIN otherTable ON ...
WHERE age > 30;

2
यदि आप "सेलेक्ट नेम, लोकेशन फ्रॉम माईटेबल" मान लेते हैं तो यूजर्स डेडटैब टेबल में डाले जा रहे मानों से कोई फर्क नहीं पड़ता अगर सिलेक्ट में वैरिएबल के नाम टेबल डेफिनिशन में नामों से मेल खाते हैं। आप उपयोगकर्ता नाम 'चर' में जाने के लिए 'नाम' का चयन कर रहे हैं, लेकिन आप 'स्थान' का चयन कर रहे हैं और किसी तरह इसे उपयोगकर्ताडेटा 'पुरानेकरण' चर में नियत कर रहे हैं। क्या एसक्यूएल सिर्फ ये स्वचालित रूप से मैप करेगा या यह किसी तरह का अपवाद फेंक देगा?
अरन मुल्होलैंड

यह नाम से कोई फर्क नहीं पड़ता, केवल कॉलम प्रकार।
क्रिस्टी

5
वाह, इस तरह की समझ में आता है, लेकिन एक ही समय में मुझ में parser बहुत बुरा लगता है :)
अरन मुल्होलैंड

मैं अद्यतन विवरण में इसका उपयोग करने में सक्षम प्रतीत नहीं हो सकता: जिस्ट लिंक
पॉल-सेबस्टियन मैनोल

1
सम्मिलित विवरण में, यदि आप कॉलम स्पष्ट रूप से घोषित नहीं करते हैं, तो वे मूल बनाएँ तालिका कथन में घोषित क्रम में मैप किए जाते हैं, जैसे चयन * करता है। इसलिए, चयनित स्टेटमेंट में स्थान @userData तालिका में पुरानेकरण में मैप किया जाता है क्योंकि चयन के परिणाम सेट में स्थान 2 की स्थिति में है, और तालिका परिभाषा में पुरानाकरण कॉलम 2 है। उस ने कहा, ऐसा कभी मत करो। स्तंभों या पंक्तियों का डेटाबेस ऑर्डर करना निर्भर नहीं करना है। इस बारे में हमेशा स्पष्ट रहें।
अनुपस्थित

94

का उद्देश्य SELECT INTOहै (डॉक्स के अनुसार, मेरा जोर)

किसी अन्य तालिका में मानों से एक नई तालिका बनाने के लिए

लेकिन आपके पास पहले से ही एक लक्ष्य तालिका है! तो तुम क्या चाहते हो

INSERTबयान एक मेज पर एक या अधिक नई पंक्तियाँ कहते हैं

आप निम्न तरीकों से डेटा मान निर्दिष्ट कर सकते हैं:

...

SELECTएक या अधिक पंक्तियों के लिए डेटा मान निर्दिष्ट करने के लिए एक सबक्वेरी का उपयोग करके , जैसे:

  INSERT INTO MyTable 
 (PriKey, Description)
        SELECT ForeignKey, Description
        FROM SomeView

और इस वाक्य रचना में, यह MyTableएक तालिका चर होने की अनुमति है ।


1
वास्तव में स्वीकार किए जाते हैं जवाब इस जानकारी को शामिल करना चाहते हैं!
डेवी ब्राउन

मुझे लगता है कि MyTable यह करने के लिए "अमान्य ऑब्जेक्ट नाम" है, इसलिए इस उत्तर से कुछ गायब है।
माइक फ्लिन

@MikeFlynn MyTableयहां आपकी वास्तविक तालिका के नाम के लिए एक प्लेसहोल्डर है । मुझे नहीं लगता है कि किसी भी असली डेटाबेस का नाम तालिका के साथ है ...MyTable
आकाशवाणी

और अगर मैं SELECT INTO के साथ एक टेबल वैरिएबल बनाना / घोषित करना चाहता हूं ...? उदाहरण के लिए, टेबल वेरिएबल के कॉलम को t1.somecolumn, t1.othercolumn, t2। * के रूप में परिभाषित करने के लिए।
आर्मंडो

27

अस्थायी डेटासेट को संग्रहीत करने के लिए आप सामान्य तालिका अभिव्यक्तियों का भी उपयोग कर सकते हैं। वे अधिक सुंदर और अनुकूल हैं:

WITH userData (name, oldlocation)
AS
(
  SELECT name, location 
  FROM   myTable    INNER JOIN 
         otherTable ON ...
  WHERE  age>30
)
SELECT * 
FROM   userData -- you can also reuse the recordset in subqueries and joins

इसे प्रेम करें! धन्यवाद।
चारपश्चमी

मुझे नहीं लगता कि यह एक प्रतिलिपि बनाता है, यदि आप हटाते हैं या उपयोगकर्ताडॉट से अपडेट करते हैं तो क्या यह आपके मूल तालिकाओं में रिकॉर्ड को हटा और अपडेट नहीं करेगा?
एट्रीऑन

हां, CTE पर DELETE और UPDATE स्रोत तालिका को तब तक संशोधित करेगा जब तक CTE
जॉइन

2
इसका नकारात्मक पक्ष यह है कि आप केवल निम्नलिखित आदेशों में सीटीई तालिका का उपयोग कर सकते हैं। यदि आपको CTE के काम नहीं करने के कारण परिणाम सेट के माध्यम से एक से अधिक पास बनाने की आवश्यकता है। ओपी को लगता है कि कई संशोधन किए जाएंगे, जिस स्थिति में यह काम नहीं करेगा - "तालिका चर में डेटा का उपयोग बाद में इसे अलग-अलग तालिकाओं में सम्मिलित करने / अद्यतन करने के लिए किया जाएगा (ज्यादातर नाबालिग के साथ एक ही डेटा की प्रतिलिपि) अद्यतन)। "
टोनी

16

आप अस्थायी तालिकाओं का उपयोग करके देख सकते हैं ... यदि आप इसे किसी एप्लिकेशन से नहीं कर रहे हैं। (इसे मैन्युअल रूप से चलाना ठीक हो सकता है)

SELECT name, location INTO #userData FROM myTable
INNER JOIN otherTable ON ...
WHERE age>30

आप तालिका को इस तरह घोषित करने के प्रयास को छोड़ देते हैं ... एडहॉक प्रश्नों के लिए मदद करता है ... यह एक स्थानीय अस्थायी तालिका बनाता है जो अन्य सत्रों में तब तक दिखाई नहीं देगा जब तक आप एक ही सत्र में न हों। हो सकता है कि अगर आप किसी ऐप से क्वेरी चला रहे हैं तो कोई समस्या हो।

यदि आपको किसी एप्लिकेशन पर चलने की आवश्यकता है, तो इस तरह घोषित किए गए चर का उपयोग करें:

DECLARE @userData TABLE(
    name varchar(30) NOT NULL,
    oldlocation varchar(30) NOT NULL
);

INSERT INTO @userData
SELECT name, location FROM myTable
INNER JOIN otherTable ON ...
WHERE age > 30;

संपादित करें: आप में से कई ने कनेक्शन से सत्र के लिए अद्यतन दृश्यता का उल्लेख किया है। वेब अनुप्रयोगों के लिए अस्थायी सारणी बनाना एक विकल्प नहीं है, क्योंकि सत्रों का पुन: उपयोग किया जा सकता है, उन मामलों में अस्थायी चर से चिपके रहते हैं


2
क्षमा करें, यह उल्लेख करना भूल गया कि मेरे पास सृजन तालिका के अधिकार नहीं हैं।
Indrek

6
एक अस्थायी बनाने के लिए थोड़ा अधिक उपरि है।
पापराजो

2
अस्थायी तालिका का उपयोग करना हमेशा सुरक्षित नहीं होता है। उदाहरण के लिए, वेब सेवाएं। सर्वर पर अधिकतम कनेक्शन को सीमित करने के लिए एक एकल कनेक्शन के साथ webservices के साथ और एसक्यूएल को थोड़ा अधिक संरक्षित करने के लिए, अस्थायी तालिका हर बार गुजरने वाली क्वेरी के लिए मौजूद होगी और वर्तमान में इसका उपयोग करने वाले किसी व्यक्ति को अधिलेखित कर सकती है।
फ्रेंक

12
@ चरण - यदि आप एक वैश्विक अस्थायी तालिका (दो हैश उपसर्ग) का उपयोग करते हैं तो आप सही हैं। हालाँकि, एक स्थानीय अस्थायी तालिका (एक हैश उपसर्ग) को एकल सत्र (उर्फ एकल कनेक्शन) से अलग किया जाएगा, इसलिए जब तक आप सभी अनुरोधों के लिए एकल कनेक्शन का उपयोग नहीं कर रहे हों, तब तक आप जिन मुद्दों पर चर्चा कर रहे हैं, वे नहीं होंगे सलाह दी)। हालांकि संभावित प्रदर्शन निहितार्थ हैं।
maf748 13

@ गज़ब ज़रूर, साइड-इफ़ेक्ट वाला कोई भी स्टेटमेंट एक में इस्तेमाल होने से बाहर रखा गया है function। मेरे अनुभव में, ज्यादातर मामलों में जहां कोई सोचता है कि उन्हें इस तरह के बयानों की आवश्यकता है, इसका वास्तव में मतलब है कि उन्हें अपने पुनर्विचार functionको कम से कम करना चाहिए - या कम से कम एक के लिए रिफ्लेक्टर procedure। अपने लिए बोल रहा हूं, कम से कम। :-)
अंडरस्कोर_ड


5

पहले एक अस्थायी तालिका बनाएँ:

चरण 1:

create table #tblOm_Temp (

    Name varchar(100),
    Age Int ,
    RollNumber bigint
)

** चरण 2: ** Temp तालिका में कुछ मान डालें।

insert into #tblom_temp values('Om Pandey',102,1347)

चरण 3: अस्थायी तालिका डेटा रखने के लिए एक तालिका परिवर्तनीय घोषित करें।

declare   @tblOm_Variable table(

    Name Varchar(100),
    Age int,
    RollNumber bigint
)

चरण 4: अस्थायी तालिका से मूल्य का चयन करें और तालिका चर में डालें।

insert into @tblOm_Variable select * from #tblom_temp

अंत में मूल्य एक अस्थायी तालिका से तालिका चर में डाला जाता है

चरण 5: तालिका चर में सम्मिलित मूल्य की जाँच कर सकते हैं।

select * from @tblOm_Variable

1

ठीक है, अब पर्याप्त प्रयास के साथ मैं नीचे प्रयोग करके @table में सम्मिलित करने में सक्षम हूं:

सम्मिलित करें @TempWithheldTable चयन
a.SuspendedReason, a.SuspendedNotes, a.SuspendedBy, OPENROWSET से a.ReasonCode (बल्क 'C: \ डेटाबेस \ WithHeld.csv', FORMATFILE = N'C: \ डेटाबेस \ Format.txt ',
ErrorFile = N'C: \ Temp \ MovieLensRatings.txt ') के रूप में;

यहां मुख्य बात डालने के लिए कॉलम का चयन करना है।


मुझे एक 'टेबल वेरिएंट घोषित करना चाहिए "@TempWithheldTable" संकलन त्रुटि संदेश
atreeon

-5

SELECT INTO का उपयोग करने का एक कारण यह है कि यह आपको IDENTITY का उपयोग करने की अनुमति देता है:

SELECT IDENTITY(INT,1,1) AS Id, name
INTO #MyTable 
FROM (SELECT name FROM AnotherTable) AS t

यह तालिका चर के साथ काम नहीं करेगा, जो बहुत बुरा है ...


6
आप एक IDENTITYस्तंभ के साथ एक तालिका चर घोषित कर सकते हैं, हालांकि।
मार्टिन स्मिथ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.