यदि संग्रहीत कार्यविधि बनाते समय तालिका मौजूद है, तब भी क्या नामांकित रिज़ॉल्यूशन को बाध्य करने का कोई तरीका है?


10

SQL सर्वर में संग्रहीत कार्यविधि बनाते समय, आपको उन तालिकाओं को संदर्भित करने की अनुमति होती है जो मौजूद नहीं हैं। लेकिन, यदि तालिका मौजूद नहीं है, तो प्रक्रिया में आपके द्वारा निर्दिष्ट कोई भी कॉलम उस तालिका में मौजूद होना चाहिए ( हटाए गए नाम समाधान )।

क्या SQL सर्वर को निर्देश देना संभव है कि वे चाहे मौजूद हों या नहीं, एक प्रक्रिया में संदर्भित सभी तालिकाओं के नाम रिज़ॉल्यूशन को टाल दें। मैं सामान्य वाक्यविन्यास जाँच रखना चाहता हूँ, इसलिए यदि संभव हो, तो सिस्टम तालिका में संग्रहीत कार्यविधि परिभाषा को हैक करना एक विकल्प नहीं है।

मुझे उम्मीद है कि ऐसा करने के लिए मेरा पूछना थोड़ा अजीब लग सकता है , इसलिए यहां कुछ पृष्ठभूमि है: मैं ऑटो सी # में लिखे गए एप्लिकेशन से तालिका की परिभाषाएं और संग्रहीत प्रक्रियाएं उत्पन्न करता हूं और मेरे लिए एसक्यूएल जरूरतों के रूप में बदलाव के लिए कोड को बदलना बहुत मुश्किल है। उन्हें। मेरा कोड "गारंटी" देता है कि स्कीमा एक लेन-देन के अनुरूप है, लेकिन वर्तमान में मैं यह गारंटी नहीं दे सकता कि स्टोर किए गए कार्यविधियों को परिभाषित करने से पहले टेबल कॉलम परिभाषित किए गए हैं जो उन्हें संदर्भित करते हैं।

नीचे C # द्वारा बनाई गई SQL का एक विहित उदाहरण है जो उस समस्या को "दिखाता है" जिसे मैं हल करने की कोशिश कर रहा हूं।

--Say this table already exists.
CREATE TABLE myTable
(
    a NVARCHAR(MAX)
)
GO

--My C# code creates something like this
BEGIN TRAN 
GO

--the stored procedure gets generated first.
CREATE PROCEDURE mySproc
AS
BEGIN
    SELECT a,b FROM myTable
END

--then the table update
ALTER TABLE myTable
    ADD b nvarchar(MAX)

COMMIT TRAN 

यह है मुझे सी # कोड में इसे ठीक करने के लिए संभव है, लेकिन मैं एक साधारण "जादू" tweak मैं एसक्यूएल में खींच सकते हैं के लिए उम्मीद कर रहा हूँ। यह मेरे लिए बहुत समय बचाएगा ।


1
क्या आप किसी भी प्रक्रिया को बनाने / बदलने से पहले सभी स्कीमा परिवर्तन की प्रक्रिया नहीं कर सकते हैं? तालिका सही होने से पहले प्रक्रिया मौजूद क्यों होनी चाहिए?
हारून बर्ट्रेंड

मैं अब कोड में उस विकल्प को शुद्ध कर रहा हूं। जिस तरह से एसक्यूएल उत्पन्न होता है वह काफी जटिल है (यह एक सरल उदाहरण था) लेकिन ऐसा लग रहा है कि यह एक पीआईटीए जितना नहीं है जितना मैंने सोचा था।
डैनियल जेम्स ब्रायर्स

2
डायनामिक एसक्यूएल से भरी अपनी संग्रहीत प्रक्रियाओं को भरकर आप इसे प्राप्त कर सकते हैं - लेकिन मैं स्कीमा परिवर्तनों को संभालने के लिए आपकी स्क्रिप्ट को बनाने की कल्पना नहीं कर सकता हूं, फिर संग्रहीत प्रक्रियाएं यह सब मुश्किल होगा। कोई भी विकल्प उजागर करने के लिए बहुत सारे विकल्प नहीं हैं कि आस्थगित नाम समाधान कैसे काम करता है। पुस्तकों पर एकमात्र प्रस्ताव जो मुझे पता है, या कम से कम जिसे मैं अनुमान लगा सकता हूं कि वे मनोरंजन में रुचि रखते हैं, वास्तव में दूसरा तरीका है - इसे और अधिक सख्त बनाना - देखें sommarskog.se/strict_checks.html )।
हारून बर्ट्रेंड

गतिशील एसक्यूएल के बारे में अच्छा विचार है। मुझे ट्रिगर, इंडेक्स, व्यूज़, स्प्रोक्स और फ़ंक्शंस के लिए समान समस्या मिली है। लेकिन मैंने कोड बदल दिया है ताकि यह सिर्फ टेबल्स में बदलाव करे, फिर इंडेक्स, फिर ट्रिगर, फिर फ़ंक्शन, फिर स्पोक्स।
डैनियल जेम्स ब्रायर्स

मुझे सोमरस्कॉग के सुझाव पसंद हैं, निश्चित रूप से कीड़े से बचने में मदद करेंगे। यदि उन्होंने एक सख्त विकल्प को लागू किया है, तो वे सभी "स्ट्रिक्ट ऑन" स्प्रोक्स का भी पुनर्मूल्यांकन कर सकते हैं जब यह देखने के लिए कि क्या यह मौजूदा स्पोक्स को तोड़ता है एक तालिका परिवर्तन है - जाहिर है आपको तब डीडीएल पर "तार्किक लेन-देन" करने की आवश्यकता होगी ताकि आप फिर एक इकाई के रूप में टेबल और स्पोक्स को बदल सकते हैं।
डैनियल जेम्स ब्रायर्स

जवाबों:


6

नहीं।

मुझे लगता है कि वास्तव में दोषी केवल टाइपिंग है, लेकिन नहीं, दुख की बात है। मैंने पहली बार इस उपयोग के मामले के बारे में सुना है, और यह बिल्कुल सही समझ में आता है। Http://connect.microsoft.com पर इसके लिए एक अनुरोध सबमिट करने के लिए सबसे अच्छा है और आपके पोते इसे करने में सक्षम होंगे। ;-)


5

बस अगर आप अभी भी रुचि रखते हैं, तो एक संभावित समाधान है जिसे आप नियोजित कर सकते हैं। यहां अपडेट किया गया कोड है, जो #deferResolutionप्रक्रिया में प्रत्येक क्वेरी के लिए अस्थायी तालिका का परिचय देता है। चूँकि अस्थायी तालिका केवल रनटाइम पर मौजूद होगी, फिर भी प्रक्रिया संकलित करने में सक्षम है, जबकि उचित कॉलम अभी तक मौजूद नहीं है myTable

यहां तक #deferResolutionकि प्रक्रिया के प्रत्येक कथन के लिए आपको एक ही निष्पादन योजना ( तालिका का कोई संदर्भ नहीं ) मिलेगी जिस तरह से क्वेरी ऑप्टिमाइज़र यह साबित कर सकता है कि यह WHERE NOT EXISTSहमेशा सही मूल्यांकन करता है।

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

--Say this table already exists.
CREATE TABLE myTable
(
    a NVARCHAR(MAX)
)
GO

--My C# code creates something like this
BEGIN TRAN 
GO

--the sproc gets generated first.
CREATE PROCEDURE mySproc
AS
BEGIN
    CREATE TABLE #deferResolution (dummy INT NOT NULL)
    SELECT a,b FROM myTable WHERE NOT EXISTS (SELECT * FROM #deferResolution WHERE 0=1)
END

--then the table update
ALTER TABLE myTable
    ADD b nvarchar(MAX)

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