सामान्य उत्तर WHERE क्लॉज जोड़ना है:
WHERE ISDATE(a.valor) = 1
हालाँकि यह आपकी स्थिति में कुछ कारणों से समस्याग्रस्त है:
-
ISDATE()
सर्वर की क्षेत्रीय सेटिंग्स, उपयोगकर्ता की भाषा या दिनांक स्वरूप विकल्पों आदि के आधार पर आवश्यक रूप से आपके इच्छित तरीके से मेल नहीं खाएगा। उदाहरण के लिए:SET DATEFORMAT dmy; SELECT ISDATE('13/01/2012'); -- 1 SET DATEFORMAT mdy; SELECT ISDATE('13/01/2012'); -- 0
-
आप वास्तव में यह नियंत्रित नहीं कर सकते कि SQL सर्वर
CONVERT
. को आजमाएगा और निष्पादित करेगा फिल्टर के बाद।
आप फ़िल्टर को CONVERT से अलग करने का प्रयास करने के लिए उपश्रेणियों या CTE का उपयोग भी नहीं कर सकते क्योंकि SQL सर्वर कर सकता है क्वेरी में संचालन को उस क्रम में अनुकूलित करें जिस क्रम में वह अधिक कुशल समझे।
उदाहरण के लिए, एक सीमित नमूने के साथ, आप शायद पाएंगे कि यह ठीक काम करता है:
SET DATEFORMAT dmy;
SELECT valor, valor_date FROM (
SELECT valor, valor_date = CONVERT(DATE,
CASE WHEN ISDATE(valor) = 1 THEN valor ELSE NULL END, 103)
FROM dbo.mytable
WHERE ISDATE(valor) = 1
) AS sub WHERE valor_date BETWEEN '01/01/2012' AND '01/03/2012';
लेकिन मैंने इस निर्माण के मामले भी देखे हैं जहां SQL सर्वर ने पहले फ़िल्टर का मूल्यांकन करने का प्रयास किया है, जिससे वही त्रुटि हो रही है जो आपको वर्तमान में मिल रही है।
कुछ सुरक्षित उपाय:
एक परिकलित कॉलम जोड़ें, उदा.
ALTER TABLE dbo.mytable ADD valor_date
AS CONVERT(DATE, CASE WHEN ISDATE(valor) = 1 THEN valor
ELSE NULL END, 103);
रनटाइम पर संभावित गलत व्याख्याओं से खुद को बचाने के लिए, आपको एक क्वेरी जारी करने से पहले दिनांक स्वरूप निर्दिष्ट करना चाहिए जो गणना किए गए कॉलम का संदर्भ देता है, उदा.
SET DATEFORMAT dmy;
SELECT valor, valor_date FROM dbo.mytable WHERE ...;
एक दृश्य बनाएं:
CREATE VIEW dbo.myview
AS
SELECT valor, valor_date = CONVERT(DATE,
CASE WHEN ISDATE(valor) = 1 THEN valor ELSE NULL END, 103)
FROM dbo.mytable
WHERE ISDATE(valor) = 1;
दोबारा, आप एक SET DATEFORMAT
. जारी करना चाहेंगे दृश्य की क्वेरी करते समय।
एक अस्थायी तालिका का प्रयोग करें:
SELECT <cols>
INTO #foo
FROM dbo.mytable
WHERE ISDATE(valor) = 1;
SELECT <cols>, CONVERT(DATE, valor) FROM #foo WHERE ...;
आप अभी भी DATEFORMAT
. का उपयोग करना चाह सकते हैं ISDATE
. के बीच संघर्ष से स्वयं को बचाने के लिए और उपयोगकर्ता सेटिंग।
और नहीं, आपको नहीं करना चाहिए दूसरे (अब हटाए गए) उत्तर में सुझाए गए स्ट्रिंग पैटर्न मिलान का उपयोग करके तारीखों के रूप में अपने स्ट्रिंग्स को सत्यापित करने का प्रयास करें:
like '%__/%' or like '%/%'
लीप वर्ष सहित सभी मान्य तिथियों को संभालने के लिए आपको कुछ बहुत ही जटिल और भारी-भरकम सत्यापन करना होगा।