sql हरण एक संग्रहीत कार्यविधि में अल्पविराम से अलग सूची कैसे पारित करें?




हिंदी चिन्हों के नाम (9)

यह एक त्वरित और गंदा तरीका है जो उपयोगी हो सकता है:

select  * 
from    mytbl 
where   "," + ltrim(rtrim(@keylist)) + "," like "%," + ltrim(rtrim(name)) + ",%"

इसलिए मेरे पास एक साइबेस संग्रहीत प्रक्रिया है जो 1 पैरामीटर को लेता है जो कि एक अल्पविराम द्वारा तारों की अलग सूची है और किसी IN () खंड में क्वेरी को चलाता है:

CREATE PROCEDURE getSomething @keyList varchar(4096)
AS
SELECT * FROM mytbl WHERE name IN (@keyList)

मैं सूची में 1 से अधिक मूल्य के साथ मेरी संग्रहीत प्रक्रिया को कैसे कॉल करूं? अभी तक मैंने कोशिश की है

exec getSomething 'John'         -- works but only 1 value
exec getSomething 'John','Tom'   -- doesn't work - expects two variables
exec getSomething "'John','Tom'" -- doesn't work - doesn't find anything
exec getSomething '"John","Tom"' -- doesn't work - doesn't find anything
exec getSomething '\'John\',\'Tom\'' -- doesn't work - syntax error

संपादित करें: मैं वास्तव में इस पृष्ठ को मिला है जिसमें एक स्प्रेक के लिए सरणी के लिए विभिन्न तरीकों का एक बड़ा संदर्भ है


इस तरह से कोशिश करो मेरे लिए यह काम करता है

@itemIds varchar(max)

CREATE PROCEDURE getSomething @keyList varchar(4096)
AS
SELECT * FROM mytbl WHERE name IN (SELECT Value FROM [Global_Split] (@itemIds,','))

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

DECLARE @idoc int
DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
   <Order CustomerID="VINET" EmployeeID="5" OrderDate="1996-07-04T00:00:00">
      <OrderDetail OrderID="10248" ProductID="11" Quantity="12"/>
      <OrderDetail OrderID="10248" ProductID="42" Quantity="10"/>
   </Order>
</Customer>
<Customer CustomerID="LILAS" ContactName="Carlos Gonzlez">
   <Order CustomerID="LILAS" EmployeeID="3" OrderDate="1996-08-16T00:00:00">
      <OrderDetail OrderID="10283" ProductID="72" Quantity="3"/>
   </Order>
</Customer>
</ROOT>'
--Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement that uses the OPENXML rowset provider.
SELECT    *
FROM       OPENXML (@idoc, '/ROOT/Customer',1)
            WITH (CustomerID  varchar(10),
                  ContactName varchar(20))

निश्चित नहीं कि यह एएसई में है, लेकिन एसक्यूएल कहीं भी, sa_split_list फ़ंक्शन एक सीएसवी से एक तालिका देता है इसमें एक भिन्न सीमांकक (डिफ़ॉल्ट एक अल्पविराम है) पास करने के लिए वैकल्पिक तर्क हैं और प्रत्येक लौटा मूल्य के लिए एक अधिकतम लंबाई है।

sa_split_list फ़ंक्शन


यह थोड़ा देर हो चुकी है, लेकिन कुछ समय पहले मुझे यह सटीक मुद्दा था और मुझे एक समाधान मिला

चाल डबल उद्धृत है और फिर उद्धरण में पूरे स्ट्रिंग को लपेटकर।

exec getSomething """John"",""Tom"",""Bob"",""Harry"""

स्ट्रिंग के लिए तालिका एंट्री से मिलान करने के लिए अपनी प्रक्रिया को संशोधित करें।

CREATE PROCEDURE getSomething @keyList varchar(4096)
AS
SELECT * FROM mytbl WHERE @keyList LIKE '%'+name+'%' 

एएसई 12.5 के बाद से मैंने इसे उत्पादन में किया है; हम अब 15.0.3 पर हैं।


अल्पविराम से अलग की गई सूची उस फ़ंक्शन में पास करें जो एक तालिका मान लौटाती है स्टैक ओव्हरफ्लो पर कहीं एक एमएस एसक्यूएल उदाहरण है, अगर मैं इसे इस समय देख सकता हूं।

CREATE PROCEDURE getSomething @keyList varchar(4096)
AS
SELECT * FROM mytbl WHERE name IN (fn_GetKeyList(@keyList))

के साथ बुलाना -

exec getSomething 'John,Tom,Foo,Bar'

मुझे लगता है कि साइबेस को कुछ ऐसा करने में सक्षम होना चाहिए?


एसक्यूएल में यह काम करता है अपने GetSomething प्रक्रिया में टाइप एक्सएक्स के एक चर के रूप में इस तरह की घोषणा करें:

DECLARE @NameArray XML = NULL

संग्रहीत कार्यप्रणाली का निकाय निम्न लागू करता है:

मेरा नाम से नाम का चयन करें (नाम ') के रूप में पैरामाव्ल्यूज (आईडी)) से मेरा चयन करें * नाम से (नाम') ',' VARCHAR (10) ')।

एसक्यूएल कोड के भीतर से जो SP को घोषित करता है और संग्रहीत कार्यविधि को कॉल करने से पहले एक्सएमएल वैरिएबल प्रारंभ करता है:

DECLARE @NameArray XML

SET @NameArray = '<id> Name_1 </ id> <id> नाम 2 </ id> <id> Name_3 </ id> <id> Name_4 </ id>'

आपके उदाहरण का उपयोग संग्रहीत कार्यविधि के लिए होगा:

एक्ज़िक गेट्समिंग @ नामअरे

मैंने पहले इस विधि का इस्तेमाल किया है और यह ठीक काम करता है। यदि आप एक त्वरित परीक्षण चाहते हैं, तो निम्न कोड को एक नई क्वेरी में कॉपी और पेस्ट करें:

DECLARE @IdArray XML

SET @IdArray = '<id> Name_1 </ id> <id> नाम 2 </ id> <id> Name_3 </ id> <id> Name_4 </ id>'

पैरामाव्यूज (आईडी) के रूप में @ IdArray.nodes ('id') से परम वैल्यू.आईडी.वल्यूए ('।', 'VARCHAR (10)') का चयन करें।


क्या @ एबेल प्रदान करने के लिए, मुझे क्या मदद मिली थी:

मेरा उद्देश्य जो भी अंत उपयोगकर्ता को एसएसआरएस से इनपुट किया गया था और उसमें प्रयोग करना था कि मेरे में जहां (इनका चयन) स्पष्ट रूप से @ICD_VALUE_RPT मेरे डेटासेट क्वेरी में टिप्पणी की जाएगी।

DECLARE @ICD_VALUE_RPT VARCHAR(MAX) SET @ICD_VALUE_RPT = 'Value1, Value2'
DECLARE @ICD_VALUE_ARRAY XML SET @ICD_VALUE_ARRAY = CONCAT('<id>', REPLACE(REPLACE(@ICD_VALUE_RPT, ',', '</id>,<id>'),' ',''), '</id>')

तो मेरे WHERE मैंने कहा:

(PATS_WITH_PL_DIAGS.ICD10_CODE IN (SELECT ParamValues.ID.value('.','VARCHAR(MAX)') FROM @ICD_VALUE_ARRAY.nodes('id') AS ParamValues(ID))
OR PATS_WITH_PL_DIAGS.ICD9_CODE IN (SELECT ParamValues.ID.value('.','VARCHAR(MAX)') FROM @ICD_VALUE_ARRAY.nodes('id') AS ParamValues(ID))
)

इस तरह की कॉलों के साथ समस्या: exec getSomething '' जॉन ',' टॉम '' यह है कि यह "जॉन", "टॉम" को एक स्ट्रिंग के रूप में इलाज कर रहा है, यह केवल तालिका में एक प्रविष्टि से मिलान करेगा जो '' जॉन "," टॉम " '।

यदि आप पॉल के जवाब में एक अस्थायी तालिका का उपयोग नहीं करना चाहते थे, तो आप गतिशील SQL का उपयोग कर सकते हैं (ग्रहण v12 +)

CREATE PROCEDURE getSomething @keyList varchar(4096)
AS
declare @sql varchar(4096)
select @sql = "SELECT * FROM mytbl WHERE name IN (" + @keyList +")"
exec(@sql)

आपको यह सुनिश्चित करना होगा कि @keylist में आइटम्स उनके चारों ओर कोट्स हैं, भले ही वे एकल मान हैं







sybase-ase