2016-02-11 4 views
11

पर आधारित है, मैं अपने कॉलम मानों के आधार पर अंकगणितीय ऑपरेशन करना चाहता हूं। निम्नलिखित उदाहरण पर विचारअंकगणित/लॉजिकल ऑपरेशन कॉलम मान

CREATE TABLE #test 
    (
    cont_sal INT, 
    check_value INT, 
    operator VARCHAR(50) 
) 

INSERT #test 
VALUES (10,20,'+'), 
     (20,10,'+'), 
     (10,20,'-'), 
     (20,10,'-') 

अपेक्षित परिणाम:

cont_sal check_value result 
-------- ----------- ------ 
10   20   30 
20   10   30 
10   20   -10 
20   10   10 

मैं इस का उपयोग कर CASE बयान कर सकते हैं।

SELECT cont_sal, 
     check_value, 
     CASE 
     WHEN operator = '+' THEN cont_sal + check_value 
     when operator = '-' THEN cont_sal - check_value 
     END result 
FROM #test 

लेकिन इस गतिशील रूप से करने के लिए कोई रास्ता नहीं है। ऑपरेटर /, %, * जैसे कुछ भी हो सकता है। इस

DECLARE @sql NVARCHAR(max)='' 

SET @sql = 'select cont_sal ' + 'operator' 
      + ' check_value from #test ' 

--PRINT @sql 

EXEC Sp_executesql 
    @sql 

की तरह जो कुछ स्पष्ट रूप से

कह संदेश 102 काम नहीं किया, स्तर 15, राज्य 1, के पास पंक्ति 1 गलत वाक्य रचना 'check_value'।

+4

'CASE' अभिव्यक्ति का प्रयोग करें। इसके बारे में कारण सबसे आसान होगा। –

+3

आपका मतलब है 'SET @sql =' cont contsal '+ @op + #test से' check_value '' – Deepshikha

+2

@ मिनी - प्रत्येक पंक्ति में इसका अपना ऑपरेटर होगा, इसलिए हम चर –

उत्तर

5

शानदार सवाल।

मैं एक मामले अभिव्यक्ति का उपयोग क्योंकि होगा:

  1. वहाँ केवल five arithmetic operators हैं।
  2. आप अंकगणितीय ऑपरेटरों को सीधे पैरामीटर नहीं कर सकते हैं।
  3. आप गतिशील एसक्यूएल इनलाइन निष्पादित नहीं कर सकते हैं।

लेकिन विकल्प हैं। आप एक गतिशील एसक्यूएल कथन बना सकते हैं और फिर निष्पादित कर सकते हैं।

-- Query will be stored here. 
DECLARE @Qry VARCHAR(255) = ''; 

-- Build up the query. 
SELECT 
    @Qry = 
     @Qry 
     + CASE ROW_NUMBER() OVER (ORDER BY cont_sal) 
       WHEN 1 THEN 'SELECT ' 
       ELSE 'UNION ALL SELECT ' 
      END 
     + '''' 
     + Expression 
     + '''' 
     + ' AS Expression,' 
     + Expression 
     + ' AS Result ' 
FROM 
    #test AS t 
     CROSS APPLY 
      (
       -- Avoid typing expression twice. 
       SELECT 
        CAST(cont_sal AS VARCHAR(50)) 
         + ' ' 
         + operator 
         + ' ' 
         + CAST(check_value AS VARCHAR(50)) AS Expression   
      ) AS ex 
; 

-- Execute it. 
EXECUTE(@Qry); 

या आप ब्रूट फोर्स का उपयोग करके परिणाम की गणना करने के लिए एक क्रॉस का उपयोग कर सकते हैं।

SELECT 
    *  
FROM 
    #test AS t 

     CROSS APPLY 
      (
       VALUES 
        ('+', cont_sal + check_value), 
        ('-', cont_sal - check_value), 
        ('*', cont_sal * check_value), 
        ('/', cont_sal/NULLIF(check_value, 0)), 
        ('%', cont_sal % NULLIF(check_value, 0)) 
      ) AS ex(operator, result) 
WHERE 
    ex.operator = t.operator 
; 

यहां हर संभव ऑपरेशन की गणना की जाती है। जिनकी आवश्यकता नहीं है वे परिणाम सेट से फ़िल्टर किए गए हैं। यह दृष्टिकोण पढ़ने और लिखना आसान है, लेकिन गणना की जाती है जो कभी भी आवश्यक नहीं होती है। उस ने कहा, यह एक तेज क्वेरी योजना उत्पन्न हुई है कि मेरे गतिशील उदाहरण।

संपादित

@Damien_The_Unbeliever, जो मेरी असुरक्षा ने बताया शून्य त्रुटियों से विभाजित करने के लिए करने के लिए धन्यवाद। मैंने NULLIF का उपयोग नल के लिए 0s को स्वैप करने के लिए किया है, जो त्रुटि से बचाता है।

मैंने केवल दूसरा उदाहरण अपडेट किया है।

+2

का उपयोग नहीं कर सकते हैं अंतिम उदाहरण - इसमें जोखिम है यहां शून्य त्रुटि से विभाजित करें यदि 'check_value' 0 है, यहां तक ​​कि पंक्तियों के लिए जहां 'ऑपरेटर' विभाजित नहीं होता है, क्योंकि सिस्टम सभी गणनाओं को चलाने का निर्णय ले सकता है। –

+0

मुझे पता था कि मैं इससे दूर नहीं जाऊंगा! अच्छा बिंदु, मैं संपादित करूँगा। –

+0

प्रयुक्त 'क्रॉस लागू करें' विधि :) –

1

अस्वीकरण: मैं परियोजना Eval SQL.NET

इस पुस्तकालय T-SQL में सीधे सी # सिंटैक्स का उपयोग करने गतिशील अंकगणितीय अभिव्यक्ति का मूल्यांकन करने की अनुमति के मालिक हूँ। ऑपरेटर प्राथमिकता और कोष्ठक सम्मानित किया जाता है और पुस्तकालय सरल गणित अभिव्यक्ति से परे रास्ता जाता है।

CREATE TABLE #test 
    (
     cont_sal INT , 
     check_value INT , 
     operator VARCHAR(50) 
    ) 

INSERT #test 
VALUES (10, 20, '+'), 
     (20, 10, '+'), 
     (10, 20, '-'), 
     (20, 10, '-') 

DECLARE @sqlnet SQLNET = SQLNET::New('') 

SELECT cont_sal , 
     check_value , 
     @sqlnet.Code('x ' + operator + ' y') 
      .Val('x', cont_sal) 
      .Val('y', check_value) 
      .Eval() 
FROM #test 

DROP TABLE #test 

प्रलेखन: SQL Server Eval - Dynamically evaluate arithmetic operation and expression

+0

धन्यवाद। इसे जांच लेंगे –

संबंधित मुद्दे