SQL सर्वर सबक्वेरी 1 से अधिक मान पर लौटा। यह अनुमति नहीं है जब उपकुंजी =;! =, <, <=>,> = = का अनुसरण करता है


84

मैं निम्नलिखित प्रश्न चलाता हूं:

SELECT 
   orderdetails.sku,
   orderdetails.mf_item_number,
   orderdetails.qty,
   orderdetails.price,
   supplier.supplierid,
   supplier.suppliername,
   supplier.dropshipfees,
   cost = (SELECT supplier_item.price
           FROM   supplier_item,
                  orderdetails,
                  supplier
           WHERE  supplier_item.sku = orderdetails.sku
                  AND supplier_item.supplierid = supplier.supplierid)
FROM   orderdetails,
       supplier,
       group_master
WHERE  invoiceid = '339740'
       AND orderdetails.mfr_id = supplier.supplierid
       AND group_master.sku = orderdetails.sku  

मुझे निम्नलिखित त्रुटि मिलती है:

एमएसजी 512, लेवल 16, स्टेट 1, लाइन 2 सबक्वेरी 1 से अधिक मूल्य पर लौटा। यह अनुमति नहीं है जब उपकुंजी का अनुसरण किया जाता है =; =; <, <=>,> = = या जब उपश्रेणी का उपयोग अभिव्यक्ति के रूप में किया जाता है।

कोई विचार?


40
ओह, और निहित सिंटैक्स का उपयोग करना बंद करो, यह एक बहुत खराब अभ्यास है, जिसे बनाए रखना और गलतियों को आसान बनाना आसान है।
HLGEM

1
@HLGEM यह गलत व्यवहार क्यों है, इसे बनाए रखना मुश्किल है और गलतियों को आसान बनाना है?
रेगैगिटेरिट

5
इन तालिकाओं को किन क्षेत्रों में शामिल किया गया है? सुझाव: तथ्य यह है कि मैं नहीं बता सकता समस्या है।
naughtilus

जवाबों:


49

इसे इस्तेमाल करे:

SELECT
    od.Sku,
    od.mf_item_number,
    od.Qty,
    od.Price,
    s.SupplierId,
    s.SupplierName,
    s.DropShipFees,
    si.Price as cost
FROM
    OrderDetails od
    INNER JOIN Supplier s on s.SupplierId = od.Mfr_ID
    INNER JOIN Group_Master gm on gm.Sku = od.Sku
    INNER JOIN Supplier_Item si on si.SKU = od.Sku and si.SupplierId = s.SupplierID
WHERE
    od.invoiceid = '339740'

यह कई पंक्तियों को लौटाएगा जो costस्तंभ को छोड़कर समान हैं । लौटाए गए विभिन्न मूल्य मूल्यों को देखें और पता लगाएं कि विभिन्न मूल्यों का क्या कारण है। फिर किसी से पूछें कि उन्हें कौन सी लागत मूल्य चाहिए, और उस मूल्य को चुनने वाले क्वेरी में मापदंड जोड़ें।


44

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

आप निष्क्रिय करने के लिए अपनी क्वेरी को संशोधित कर सकते हैं तो ट्रिगर को सक्षम करें यदि ट्रिगर जो चलाने की कोशिश कर रहे हैं उसके लिए आपको निष्पादित करने की आवश्यकता नहीं है।

ALTER TABLE your_table DISABLE TRIGGER [the_trigger_name]

UPDATE    your_table
SET     Gender = 'Female'
WHERE     (Gender = 'Male')

ALTER TABLE your_table ENABLE TRIGGER [the_trigger_name]

4
क्या उन्हें अक्षम करने के बजाय ट्रिगर को ठीक करना बेहतर नहीं होगा? उन ट्रिगर को एक कारण के लिए बनाया गया था, नहीं? आप ट्रिगर को अक्षम करके कुछ महत्वपूर्ण कार्यक्षमता को बायपास कर सकते हैं ...
टीटी।

3
@ टीटी। हां, लेकिन कृपया उत्तर में बोल्ड टेक्स्ट देखें। आप निष्क्रिय करने के लिए अपनी क्वेरी को संशोधित कर सकते हैं तो ट्रिगर को सक्षम करें यदि ट्रिगर जो चलाने की कोशिश कर रहे हैं, उसके लिए निष्पादित करने की आवश्यकता नहीं है।
जे.के.

1
क्वेरी के दौरान तालिका को बदलना बिल्कुल भयानक है। यदि आपको ट्रिगर छोड़ने की आवश्यकता है, तो इसे प्रति-कनेक्शन के आधार पर करें।
बेन वायगेट

26
SELECT COLUMN 
    FROM TABLE 
WHERE columns_name
    IN ( SELECT COLUMN FROM TABLE WHERE columns_name = 'value');

ध्यान दें: जब हम उप-क्वेरी का उपयोग कर रहे हैं तो हमें इन बिंदुओं पर ध्यान देना चाहिए:

  1. यदि हमारी उप क्वेरी इस मामले में 1 मान लौटाती है, तो हमें (=; =!, <>, <,> ....) का उपयोग करना होगा।
  2. अन्य (एक से अधिक मूल्य), इस मामले में हमें (किसी, सभी, कुछ) का उपयोग करने की आवश्यकता है

13
cost = Select Supplier_Item.Price from Supplier_Item,orderdetails,Supplier 
   where Supplier_Item.SKU=OrderDetails.Sku and 
      Supplier_Item.SupplierId=Supplier.SupplierID

यह सबक्वेरी कई मान लौटाता है, SQL शिकायत कर रहा है क्योंकि यह एक ही रिकॉर्ड में लागत के लिए कई मान निर्दिष्ट नहीं कर सकता है।

कुछ विचार:

  1. डेटा को ठीक करें जैसे कि मौजूदा उपश्रेणी केवल 1 रिकॉर्ड देता है
  2. उपश्रेणी को ठीक करें जैसे कि यह केवल एक रिकॉर्ड देता है
  3. एक शीर्ष 1 को जोड़ें और सबक्वेरी द्वारा आदेश दें (गंदा समाधान जिसे डीबीए नफरत करते हैं - लेकिन यह "काम करता है")
  4. एक स्ट्रिंग में उपकुंजी के परिणामों को संक्षिप्त करने के लिए एक उपयोगकर्ता परिभाषित फ़ंक्शन का उपयोग करें

5
3 पर; सभी सक्षम डेवलपर्स को भी नफरत करनी चाहिए। थोड़ी देर पहले 'पेट पीव्स' पर एक सवाल था; और मेरा होगा: "सिर्फ इसलिए कि कोई त्रुटि संदेश नहीं है, इसका मतलब यह नहीं है कि यह 'काम करता है!"। उस ने कहा, आप # 5 जोड़ सकते हैं: पूरी क्वेरी को फिर से संगठित करें; ग्राहक पाने और 'लुक-अप' चालान के बजाय; बल्कि चालान और 'लुकअप' ग्राहक पाएं।
मोहभंग

10

या तो आपका डेटा खराब है, या यह आपके सोचने के तरीके को संरचित नहीं करता है। संभवतः दोनों।

इस परिकल्पना को साबित / अस्वीकृत करने के लिए, इस प्रश्न को चलाएं:

SELECT * from
(
    SELECT count(*) as c, Supplier_Item.SKU
    FROM Supplier_Item
    INNER JOIN orderdetails
        ON Supplier_Item.sku = orderdetails.sku
    INNER JOIN Supplier
        ON Supplier_item.supplierID = Supplier.SupplierID
    GROUP BY Supplier_Item.SKU
) x
WHERE c > 1
ORDER BY c DESC

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

मैं अनुमान लगा रहा हूं कि आपके पास SKUकई बार (दो अलग लाइन आइटम, दोनों समान ऑर्डर करने वाले SKU) ऑर्डर हैं ।


10

इसके बजाय सहसंबद्ध उपश्रेणियों का उपयोग बंद करना है और इसके बजाय जोड़ का उपयोग करना है। सहसंबद्ध उपश्रेणियाँ अनिवार्य रूप से अभिशाप हैं क्योंकि वे क्वेरी को पंक्ति-दर-पंक्ति चलाने का कारण बनते हैं और उन्हें टाला जाना चाहिए।

यदि आप केवल एक रिकॉर्ड मैच के लिए चाहते हैं, तो आपको इस फ़ील्ड में शामिल होने के लिए एक व्युत्पन्न तालिका की आवश्यकता हो सकती है, अगर आपको दोनों मानों की आवश्यकता है, तो साधारण joinऐसा करेगा, लेकिन आपको एक ही आईडी के लिए कई रिकॉर्ड मिलेंगे परिणाम सेट में। आप केवल एक चाहते हैं, आप जो एक तय करने के लिए की जरूरत है और है कि कोड में, आप एक इस्तेमाल कर सकते हैं कर top 1एक साथ order by, आप इस्तेमाल कर सकते हैं max(), तो आप इस्तेमाल कर सकते हैं min(), आदि, डेटा के लिए अपनी वास्तविक आवश्यकता है, उसके आधार पर।


9

मुझे एक ही समस्या थी, मैंने inइसके बजाय डेटाबेस उदाहरण =से उपयोग किया Northwind:

क्वेरी है: उन कंपनियों का पता लगाएं, जिन्होंने 1997 में ऑर्डर दिए थे

इसे इस्तेमाल करे :

SELECT CompanyName
    FROM Customers
WHERE CustomerID IN (
                        SELECT CustomerID 
                            FROM Orders 
                        WHERE YEAR(OrderDate) = '1997'
                    );

उसके बदले में :

SELECT CompanyName
    FROM Customers
WHERE CustomerID =
(
    SELECT CustomerID 
        FROM Orders 
    WHERE YEAR(OrderDate) = '1997'
);

6

आपके चयन के मूल्य भाग में चयनित विवरण एक से अधिक मान लौटा रहा है। आपको और अधिक जोड़ने की आवश्यकता है जहां खंड, या एक एकत्रीकरण का उपयोग करते हैं।


4

त्रुटि का तात्पर्य है कि यह उपश्रेणी 1 से अधिक पंक्ति में लौट रही है:

(Select Supplier_Item.Price from Supplier_Item,orderdetails,Supplier where Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID )

आप संभवतः उप-क्रम में आदेश-तालिका और आपूर्तिकर्ता तालिका को शामिल नहीं करना चाहते, क्योंकि आप बाहरी क्वेरी में उन तालिकाओं से चयनित मानों को संदर्भित करना चाहते हैं। इसलिए मुझे लगता है कि आप चाहते हैं कि उपकुंजी बस हो:

(Select Supplier_Item.Price from Supplier_Item where Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID )

मेरा सुझाव है कि आप सहसंबद्ध बनाम गैर-सहसंबद्ध उपश्रेणियों पर पढ़ें।


3

जैसा कि दूसरों ने सुझाव दिया है, ऐसा करने का सबसे अच्छा तरीका चर असाइनमेंट के बजाय जॉइन का उपयोग करना है। किसी ज्वाइन का उपयोग करने के लिए अपनी क्वेरी को फिर से लिखना (और निहित ज्वाइन के बजाय स्पष्ट जॉइन सिंटैक्स का उपयोग करना, जो कि सुझाव भी दिया गया था - और सबसे अच्छा अभ्यास है), आपको कुछ इस तरह मिलेगा:

select  
  OrderDetails.Sku,
  OrderDetails.mf_item_number,
  OrderDetails.Qty,
  OrderDetails.Price,
  Supplier.SupplierId, 
  Supplier.SupplierName,
  Supplier.DropShipFees, 
  Supplier_Item.Price as cost
from 
  OrderDetails
join Supplier on OrderDetails.Mfr_ID = Supplier.SupplierId
join Group_Master on Group_Master.Sku = OrderDetails.Sku 
join Supplier_Item on 
  Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID 
where 
  invoiceid='339740' 

1

मूल पद के 9 साल बाद भी, इससे मुझे मदद मिली।

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

 "System.Data.SqlClient.SqlException (0x80131904): Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
    The statement has been terminated."

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

SET @Variable1 =(
        SELECT column_gonna_asign
        FROM dbo.your_db
        WHERE Non_primary_non_unique_key= @Variable2

यदि यह कई पंक्तियों को लौटाता है, तो आप मुसीबत में हैं।

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