दिलचस्प पोस्ट
मैं नेस्टेड / रिकर्सिव डिक्शनरी और लिस्ट में deserialize करने के लिए JSON.NET का उपयोग कैसे करूं? सी ++ मानक कहां बिल्कुल एक अनियिनित पॉइंटर को डिफरेंसिंग करना अपरिभाषित व्यवहार है? मैं T-SQL संग्रहीत कार्यविधि में वैकल्पिक पैरामीटर कैसे उपयोग कर सकता हूं? किसी इंटेंट का उपयोग करके गतिविधि से सेवा का डेटा पास करें मैं विंडोज सिस्टम समय मिलीसेकंड संकल्प के साथ कैसे प्राप्त करूं? स्ट्रिंग मान का उपयोग करके एक चर नाम बनाना बल में अतिरंजना मेनू ActionBarSherlock MySQL तालिका में सीएसवी आयात करें क्या शफ़ल करने के लिए JavaScript Array.sort () विधि का उपयोग करना सही है? जब एक चर का मूल्य बदल जाता है तो ईवेंट को ट्रिगर कैसे करें? एक एसक्यूएल इन खंड पैरामीटर बनाना जावा: किसी दूसरे वर्ग से तरीकों तक कैसे पहुंचें JAX-RS एप्लिकेशन को केवल एनोटेशन का उपयोग कैसे करें (कोई web.xml) नहीं है? रेखा खींचें और उसे पैनल में कैसे चुनें PHP काम नहीं कर रहा है – विंडोज 7 64 बिट पर WAMP

एक संग्रहीत कार्यविधि के लिए पैरामीटर की एक सरणी उत्तीर्ण करना

मुझे सरणी में id के मिलान वाली पंक्तियों को छोड़कर तालिका से सभी पंक्तियों को हटाने के लिए "आईडी" की एक सरणी को एक संग्रहीत कार्यविधि में पास करना होगा।

मैं इसे सबसे सरल तरीके से कैसे कर सकता हूं?

वेब के समाधान से एकत्रित समाधान "एक संग्रहीत कार्यविधि के लिए पैरामीटर की एक सरणी उत्तीर्ण करना"

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

संपादित करें: सूचीबद्ध करने के लिए एक पूरक (या कुछ और):

List<string> testList = new List<int>(); testList.Add(1); testList.Add(2); testList.Add(3); XmlSerializer xs = new XmlSerializer(typeof(List<int>)); MemoryStream ms = new MemoryStream(); xs.Serialize(ms, testList); string resultXML = UTF8Encoding.UTF8.GetString(ms.ToArray()); 

परिणाम (XML पैरामीटर के साथ उपयोग करने के लिए तैयार):

 <?xml version="1.0"?> <ArrayOfInt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <int>1</int> <int>2</int> <int>3</int> </ArrayOfInt> 

मूल पोस्ट:

पैरामीटर के रूप में XML पासिंग करना:

 <ids> <id>1</id> <id>2</id> </ids> 

 CREATE PROCEDURE [dbo].[DeleteAllData] ( @XMLDoc XML ) AS BEGIN DECLARE @handle INT EXEC sp_xml_preparedocument @handle OUTPUT, @XMLDoc DELETE FROM YOURTABLE WHERE YOUR_ID_COLUMN NOT IN ( SELECT * FROM OPENXML (@handle, '/ids/id') WITH (id INT '.') ) EXEC sp_xml_removedocument @handle 

यदि आप एसक्यूएल सर्वर 2008 या बेहतर उपयोग कर रहे हैं, तो आप हर बार जब आप एक संग्रहीत कार्यविधि में इसे पारित करना चाहते हैं, तो आप अपने सूची डेटा को सीरियललाइज और डिसेरीलाइज करने के बजाय तालिका-वैल्यू पैरामीटर (टीवीपी) नामक कुछ का उपयोग कर सकते हैं।

आइए हमारे खेल का मैदान के रूप में सेवा करने के लिए एक सरल स्कीमा बनाकर शुरू करें:

 CREATE DATABASE [TestbedDb] GO USE [TestbedDb] GO /* First, setup the sample program's account & credentials*/ CREATE LOGIN [testbedUser] WITH PASSWORD=N'µ×? ?S[°¿Q¥½q?_Ĭ¼Ð)3õļ%dv', DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english], CHECK_EXPIRATION=OFF, CHECK_POLICY=ON GO CREATE USER [testbedUser] FOR LOGIN [testbedUser] WITH DEFAULT_SCHEMA=[dbo] GO EXEC sp_addrolemember N'db_owner', N'testbedUser' GO /* Now setup the schema */ CREATE TABLE dbo.Table1 ( t1Id INT NOT NULL PRIMARY KEY ); GO INSERT INTO dbo.Table1 (t1Id) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); GO 

जगह में हमारे स्कीमा और नमूना डेटा के साथ, अब हम हमारी TVP संग्रहित प्रक्रिया बनाने के लिए तैयार हैं:

 CREATE TYPE T1Ids AS Table ( t1Id INT ); GO CREATE PROCEDURE dbo.FindMatchingRowsInTable1( @Table1Ids AS T1Ids READONLY ) AS BEGIN SET NOCOUNT ON; SELECT Table1.t1Id FROM dbo.Table1 AS Table1 JOIN @Table1Ids AS paramTable1Ids ON Table1.t1Id = paramTable1Ids.t1Id; END GO 

जगह में हमारी स्कीमा और एपीआई दोनों के साथ, हम अपने कार्यक्रम से टीवीप संग्रहित प्रक्रिया को इसी तरह कॉल कर सकते हैं:

  // Curry the TVP data DataTable t1Ids = new DataTable( ); t1Ids.Columns.Add( "t1Id", typeof( int ) ); int[] listOfIdsToFind = new[] {1, 5, 9}; foreach ( int id in listOfIdsToFind ) { t1Ids.Rows.Add( id ); } // Prepare the connection details SqlConnection testbedConnection = new SqlConnection( @"Data Source=.\SQLExpress;Initial Catalog=TestbedDb;Persist Security Info=True;User ID=testbedUser;Password=letmein12;Connect Timeout=5" ); try { testbedConnection.Open( ); // Prepare a call to the stored procedure SqlCommand findMatchingRowsInTable1 = new SqlCommand( "dbo.FindMatchingRowsInTable1", testbedConnection ); findMatchingRowsInTable1.CommandType = CommandType.StoredProcedure; // Curry up the TVP parameter SqlParameter sqlParameter = new SqlParameter( "Table1Ids", t1Ids ); findMatchingRowsInTable1.Parameters.Add( sqlParameter ); // Execute the stored procedure SqlDataReader sqlDataReader = findMatchingRowsInTable1.ExecuteReader( ); while ( sqlDataReader.Read( ) ) { Console.WriteLine( "Matching t1ID: {0}", sqlDataReader[ "t1Id" ] ); } } catch ( Exception e ) { Console.WriteLine( e.ToString( ) ); } /* Output: * Matching t1ID: 1 * Matching t1ID: 5 * Matching t1ID: 9 */ 

संभव है कि ऐसा करने के लिए एक कम दर्दनाक तरीका अधिक अमूर्त एपीआई, जैसे इकाई फ़्रेमवर्क का उपयोग कर। हालांकि, मेरे पास अब इस समय के लिए देखने का समय नहीं है

यह सबसे अच्छा स्रोत है:

http://www.sommarskog.se/arrays-in-sql.html

लिंक का उपयोग करते हुए विभाजन फ़ंक्शन बनाते हैं, और इसे इस तरह प्रयोग करें:

 DELETE YourTable FROM YourTable d LEFT OUTER JOIN dbo.splitFunction(@Parameter) s ON d.ID=s.Value WHERE s.Value IS NULL 

मैं संख्या तालिका दृष्टिकोण को पसंद करता हूं

यह उपरोक्त लिंक पर आधारित कोड है जो आपके लिए यह करना चाहिए …

अपने फ़ंक्शन का उपयोग करने से पहले, आपको एक "सहायक" तालिका सेट अप करने की आवश्यकता है, आपको प्रति डेटाबेस केवल एक बार करना होगा:

 CREATE TABLE Numbers (Number int NOT NULL, CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] DECLARE @x int SET @x=0 WHILE @x<8000 BEGIN SET @x=@x+1 INSERT INTO Numbers VALUES (@x) END 

इस स्ट्रिंग को विभाजित करने के लिए इस फ़ंक्शन का उपयोग करें, जो लूप नहीं है और बहुत तेज़ है:

 CREATE FUNCTION [dbo].[FN_ListToTable] ( @SplitOn char(1) --REQUIRED, the character to split the @List string on ,@List varchar(8000) --REQUIRED, the list to split apart ) RETURNS @ParsedList table ( ListValue varchar(500) ) AS BEGIN /** Takes the given @List string and splits it apart based on the given @SplitOn character. A table is returned, one row per split item, with a column name "ListValue". This function workes for fixed or variable lenght items. Empty and null items will not be included in the results set. Returns a table, one row per item in the list, with a column name "ListValue" EXAMPLE: ---------- SELECT * FROM dbo.FN_ListToTable(',','1,12,123,1234,54321,6,A,*,

,,,,B') returns: ListValue ———– 1 12 123 1234 54321 6 A *

B (10 row(s) affected) **/ —————- –SINGLE QUERY– –this will not return empty rows —————- INSERT INTO @ParsedList (ListValue) SELECT ListValue FROM (SELECT LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number – 1))) AS ListValue FROM ( SELECT @SplitOn + @List + @SplitOn AS List2 ) AS dt INNER JOIN Numbers n ON n.Number < LEN(dt.List2) WHERE SUBSTRING(List2, number, 1) = @SplitOn ) dt2 WHERE ListValue IS NOT NULL AND ListValue!='' RETURN END –Function FN_ListToTable

आप इस फ़ंक्शन को किसी शामिल में एक तालिका के रूप में उपयोग कर सकते हैं:

 SELECT Col1, COl2, Col3... FROM YourTable INNER JOIN dbo.FN_ListToTable(',',@YourString) s ON YourTable.ID = s.ListValue 

यहां आपका डिलीट है:

 DELETE YourTable FROM YourTable d LEFT OUTER JOIN dbo.FN_ListToTable(',',@Parameter) s ON d.ID=s.ListValue WHERE s.ListValue IS NULL 

आप यह कोशिश कर सकते हैं:

 DECLARE @List VARCHAR(MAX) SELECT @List = '1,2,3,4,5,6,7,8' EXEC( 'DELETE FROM TABLE WHERE ID NOT IN (' + @List + ')' ) 

आप एक अस्थायी तालिका का उपयोग कर सकते हैं जो संग्रहीत कार्यविधि की मौजूदगी की अपेक्षा करते हैं। यह SQL सर्वर के पुराने संस्करणों पर काम करेगा, जो XML आदि का समर्थन नहीं करते हैं।

 CREATE TABLE #temp (INT myid) GO CREATE PROC myproc AS BEGIN DELETE YourTable FROM YourTable LEFT OUTER JOIN #temp T ON T.myid=s.id WHERE s.id IS NULL END 
 declare @ids nvarchar(1000) set @ids = '100,2,3,4,5' --Parameter passed set @ids = ',' + @ids + ',' select * from TableName where charindex(',' + CAST(Id as nvarchar(50)) + ',', @ids) > 0 

मैं अपने आईडी को एक्सएमएल स्ट्रिंग के रूप में पास करने पर विचार करूँगा, और उसके बाद आप एक्सएमएल को अस्थायी तालिका में टुकड़े कर सकते हैं, या आप एसपी_XML_PREPAREDOCUMENT और ओपनएक्सएमएल का इस्तेमाल कर सीधे एक्सएमएल के विरुद्ध भी पूछ सकते हैं।

सरणी को पारित करने के बजाय XML डेटा प्रकार का उपयोग करने के बारे में मुझे लगता है कि एक बेहतर समाधान है और SQL 2005 में अच्छी तरह से काम करता है

मुझे यह पसंद है, क्योंकि यह एक XElement के रूप में पारित करने के लिए उपयुक्त है, जो कि SqlCommand के लिए उपयुक्त है

(माफ करना यह VB.NET है लेकिन आपको यह विचार मिलता है)

 <Extension()> Public Function ToXml(Of T)(array As IEnumerable(Of T)) As XElement Return XElement.Parse( String.Format("<doc>{0}</doc>", String.Join("", array.Select(Function(s) String.Concat("<d>", s.ToString(), "</d>")))), LoadOptions.None) End Function 

यह एसक्यूएल संग्रहीत प्रोसेस, छोटा, पूरा नहीं हुआ है!

कार्यप्रणाली बनाएं [डीबीओ]। [मायप्रोक] (@ ब्लाह एक्सएमएल)
एएस … डॉक (टी) के रूप में @ नेटवर्किड्स। नोड्स (एन '/ डॉक्टर / डी') से एलेक्टेड (एक्ट इन डॉक.t.value ('।', 'Int'))

SQL सर्वर 2016 में आप सरणी को [] के साथ लपेटकर इसे JSON के रूप में पास कर सकते हैं http://blogs.msdn.com/b/sqlserverstorageengine/archive/2015/09/08/passing-arrays-to-t-sql-procedures -as-json.aspx