अदिश चर घोषित करना चाहिए


81

@RowFrom int

@RowTo int

Exec(@sqlstatement)स्टोर किए गए प्रक्रिया के लिए दोनों ग्लोबल इनपुट परमेस हैं, और जब से मैं टी-एसक्यूएल के साथ संग्रहीत प्रक्रिया के अंदर SQL क्वेरी का संकलन कर रहा हूं, तब परिणाम दिखाने के लिए संग्रहीत प्रक्रिया के अंत में उपयोग कर रहा है , यह मुझे यह त्रुटि देता है जब मैं उपयोग करने का प्रयास करता हूं @RowFromया @RowToअंदर @sqlstatementचर कि निष्पादित किया जाता है .. यह ठीक अन्यथा काम करता है .. कृपया मदद करते हैं।

"Must declare the scalar variable "@RowFrom"."

इसके अलावा, मैंने @sqlstatementचर में निम्नलिखित को शामिल करने की कोशिश की :

'Declare @Rt int'
'SET @Rt = ' + @RowTo

लेकिन @RowToअभी भी इसके मूल्य को पारित नहीं करता है @Rt और एक त्रुटि उत्पन्न करता है।


5
मैं एक उत्तर नहीं जोड़ूंगा क्योंकि यह विशेष रूप से इस प्रश्न पर लागू नहीं होता है, लेकिन इस त्रुटि के लिए Google पर पहला परिणाम यह ध्यान देने योग्य है कि GOएक नई शाखा का उपयोग करने के कारण जहां घोषित चर कथन के अतीत में दिखाई नहीं देते हैं।
आयरनसन जूल

जवाबों:


75

आप एक स्ट्रिंग के लिए एक intatenate नहीं कर सकते। के बजाय:

SET @sql = N'DECLARE @Rt int; SET @Rt = ' + @RowTo;

आप की जरूरत है:

SET @sql = N'DECLARE @Rt int; SET @Rt = ' + CONVERT(VARCHAR(12), @RowTo);

यह बताने के लिए कि यहाँ क्या हो रहा है। मान लीजिये @RowTo = 5

DECLARE @RowTo int;
SET @RowTo = 5;

DECLARE @sql nvarchar(max);
SET @sql = N'SELECT ' + CONVERT(varchar(12), @RowTo) + ' * 5';
EXEC sys.sp_executesql @sql;

इसे एक स्ट्रिंग में बनाने के लिए (भले ही अंततः यह एक संख्या होगी), मुझे इसे परिवर्तित करने की आवश्यकता है। लेकिन जैसा कि आप देख सकते हैं, संख्या को अभी भी संख्या के रूप में माना जाता है जब इसे निष्पादित किया जाता है। उत्तर 25 है, है ना?

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

SET @sql = @sql + ' WHERE RowNum BETWEEN ' 
    + CONVERT(varchar(12), @RowFrom) + ' AND ' 
    + CONVERT(varchar(12), @RowTo);

यद्यपि उचित परिमाणीकरण करना बेहतर होगा, उदाहरण के लिए

SET @sql = @sql + ' WHERE RowNum BETWEEN @RowFrom AND @RowTo;';

EXEC sys.sp_executesql @sql,
  N'@RowFrom int, @RowTo int',
  @RowFrom, @RowTo;

2
धन्यवाद, लेकिन N 'क्या करता है?
बिल

3
यह सुनिश्चित करता है कि आपके @sqlचर को सही ढंग से व्याख्या किया गया है NVARCHAR- एक आवश्यकता यदि उपयोग किया जा रहा है sp_executesql...
हारून बर्ट्रेंड

1
खैर उन्हें इंट होने की जरूरत है क्योंकि इसका इस तरह इस्तेमाल किया जा रहा है "व्हॉट राउनम बिच @RowFrom और @RowTo" इस परम @ RowFrom / @ RowTo इंट के साथ-साथ डिक्लेयर भी किया गया है
बिल

4
हाँ, समझा। आप एक SQL स्ट्रिंग बना रहे हैं, और आप दो स्तरों पर हैं। शीर्ष स्तर पर, आप एक स्ट्रिंग का निर्माण कर रहे हैं - यह सब किंतु स्ट्रिंग मान के साथ होना चाहिए, भले ही वे '5' या 'फू' या 'ज़ुल्क्सक्सी' हों। मैं उदाहरण के लिए वर्णन करूँगा।
आरोन बर्ट्रेंड

9

यदि आपको चर को इससे पहले घोषित किया गया है GOऔर उसके बाद संदर्भित किया गया है, तो आप यह त्रुटि संदेश भी प्राप्त कर सकते हैं ।

इस प्रश्न और इस समाधान को देखें ।


6

सिर्फ FYI करें, मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन डेटाबेस संकलन सेटिंग्स के आधार पर आप इस तरह के एक बयान पर यह त्रुटि प्राप्त कर सकते हैं,

SET @sql = @Sql + ' WHERE RowNum BETWEEN @RowFrom AND @RowTo;';

यदि उदाहरण के लिए आप S में टाइप करते हैं

SET @sql = @***S***ql 

पहले से ही यहां पोस्ट किए गए उत्तरों को स्पिन करने के लिए क्षमा करें, लेकिन यह रिपोर्ट की गई त्रुटि का एक वास्तविक उदाहरण है।

यह भी ध्यान दें कि त्रुटि संदेश में पूंजी एस प्रदर्शित नहीं करेगी, मुझे यकीन नहीं है कि क्यों, लेकिन मुझे लगता है कि यह है क्योंकि

Set @sql =

बराबर चिह्न के बाईं ओर है।


3

बस इसे जोड़ने के लिए जो मेरे लिए तय है, जहां गलत वर्तनी इस MSDN ब्लॉग के अनुसार संदिग्ध है ...

जब एकाधिक लाइनों पर SQL स्ट्रिंग्स को विभाजित करते हैं, तो जांच लें कि आप अपने एसक्यूएल स्ट्रिंग को अपने मापदंडों से अलग कर रहे हैं (और उन्हें अलग करने की कोशिश नहीं कर रहे हैं!) और प्रत्येक स्प्लिट लाइन के अंत में किसी भी स्थान को गायब न करें। रॉकेट साइंस नहीं, लेकिन उम्मीद है कि मैं किसी को सिरदर्द से बचाऊंगा।

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

db.TableName.SqlQuery(
    "SELECT Id, Timestamp, User " +
    "FROM dbo.TableName " +
    "WHERE Timestamp >= @from " +
    "AND Timestamp <= @till;" + [USE COMMA NOT CONCATENATE!]
    new SqlParameter("from", from),
    new SqlParameter("till", till)),
    .ToListAsync()
    .Result;

0

केस सेंसिटिविटी इस समस्या का कारण होगी।

SQL सर्वर मैन में @MyVariable और @myvariable एक ही चर हैं। स्टूडियो और काम करेगा। हालाँकि, इन चर का परिणाम केस-सेंसिटिविटी अंतर के कारण Visual Studio (C #) में "स्केलर वैरिएबल" @MyVariable घोषित करना होगा।


0

भविष्य के लिए बस एक जवाब मुझे (शायद यह किसी और की भी मदद करता है!)। यदि आप क्वेरी संपादक में ऐसा कुछ चलाने की कोशिश करते हैं:

USE [Dbo]
GO

DECLARE @RC int

EXECUTE @RC = [dbo].[SomeStoredProcedure] 
   2018
  ,0
  ,'arg3'
GO

SELECT month, SUM(weight) AS weight, SUM(amount) AS amount 
FROM SomeTable AS e 
WHERE year = @year AND type = 'M'

और आपको त्रुटि मिलती है:

अदिश चर "@year" घोषित करना चाहिए

ऐसा इसलिए है क्योंकि आप कोड का एक गुच्छा चलाने की कोशिश कर रहे हैं जिसमें BOTH संग्रहीत कार्यविधि निष्पादन और इसके नीचे क्वेरी (!) शामिल है। जिसको आप चलाना या हटाना / टिप्पणी नहीं करना चाहते हैं, उस पर प्रकाश डालें।


0

अगर किसी और को इस सवाल का सामना करना पड़ता है, जबकि यहाँ कोई समाधान नहीं मेरी sql फ़ाइल काम कर रहा है, यहाँ मेरी गलती क्या थी:

मैं अपने डेटाबेस की सामग्री को माइक्रोसेफ्ट्स के सर्वर प्रबंधन स्टूडियो की 'जनरेट स्क्रिप्ट' कमांड के माध्यम से निर्यात कर रहा हूं और फिर उत्पन्न डेटा को किसी अन्य उदाहरण में सम्मिलित करते हुए कुछ ऑपरेशन कर रहा हूं।

उत्पन्न निर्यात के कारण, sql फ़ाइल में "GO" स्टेटमेंट्स का एक गुच्छा बन गया है।

मुझे नहीं पता था कि किसी फ़ाइल के शीर्ष पर घोषित चर अभी तक सुलभ नहीं हैं, जहां तक ​​कि GO कथन निष्पादित नहीं किया गया है। इसलिए मुझे अपनी sql फ़ाइल में GO स्टेटमेंट को हटाना पड़ा और त्रुटि "स्केलर वैरिएबल xy घोषित करना चाहिए" चली गई!


0

यह सबसे अधिक संभावना है कि इस समस्या का जवाब नहीं है, लेकिन यह प्रश्न पहले परिणाम के रूप में पॉप अप करता है, Sql declare scalar variableइसलिए जब मैं इस त्रुटि का संभावित समाधान साझा करता हूं

मेरे मामले में यह त्रुटि ;SQL कथन के बाद के उपयोग के कारण हुई थी । बस इसे हटा दें और त्रुटि हो जाएगी।

मुझे लगता है कि इसका कारण वैसा ही है जैसा @IronSean पहले से ही एक टिप्पणी में पोस्ट किया गया है:

यह ध्यान देने योग्य है कि GO (या इस मामले में) का उपयोग करके एक नई शाखा का कारण बनता है जहां घोषित चर कथन के अतीत में दिखाई नहीं देते हैं।

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

DECLARE @id int
SET @id = 78

SELECT * FROM MyTable WHERE Id = @var; <-- remove this character to avoid the error message
SELECT * FROM AnotherTable WHERE MyTableId = @var
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.