17

मैं कुछ विशिष्ट मूल्य के साथ विशिष्ट स्तंभ के साथ सभी तालिकाओं खोजने के लिए इस क्वेरी लिखने के लिए कोशिश कर रहा हूँ से मिलने का चयन करें। यह मैं अब तक क्या किया है है -एसक्यूएल सर्वर sp_msforeachtable उपयोग केवल उन तालिकाओं जो कुछ हालत

EXEC sp_MSforeachtable 
@command1=' 
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=PARSENAME("?",2) AND TABLE_NAME=PARSENAME("?",1) AND COLUMN_NAME="EMP_CODE") 
BEGIN 
    IF (SELECT COUNT(*) FROM ? WHERE EMP_CODE="HO081")>0 
    BEGIN 
     SELECT * FROM ? WHERE EMP_CODE="HO081" 
    END 
END 
' 

मुझे आशा है कि मेरे इरादों स्पष्ट हैं, मैं तो बस केवल उन तालिकाओं का चयन करने के जहां स्तंभ EMP_CODE वर्तमान और उन तालिकाओं में है चाहता हूँ मैं उन पंक्तियों का चयन करना चाहते हैं जहां EMP_CODE='HO081'

संपादित करें -

अब यह इस तरह खड़ा है। लेकिन मैं क्वेरी में @EMPCODE वैरिएबल को प्रतिस्थापित करने में सक्षम नहीं हूं।

DECLARE @EMPCODE AS VARCHAR(20) 
SET @EMPCODE='HO081' 
EXEC sp_MSforeachtable 
@command1=' 
    DECLARE @COUNT AS INT 
    SELECT @COUNT=COUNT(*) FROM ? WHERE EMP_CODE='''[email protected]+''' 
    IF @COUNT>0 
    BEGIN 
     PRINT PARSENAME("?",1)+'' => ''+CONVERT(VARCHAR,@COUNT)+'' ROW(S)'' 
     --PRINT ''DELETE FROM ''+PARSENAME("?",1)+'' WHERE EMP_CODE='''''[email protected]+''''''' 
    END 
',@whereand='AND O.ID IN (SELECT OBJECT_ID FROM SYS.COLUMNS C WHERE C.NAME='''[email protected]+''')' 

उत्तर

45

तुम्हें पता है कि sp_MSforeachtable undocumented है, और किसी भी समय दूर जा सकते हैं/संशोधित किया जा?

ठीक है, अगर आपको लगता है कि अनदेखी करने के लिए खुश हैं, तो यह एक और पैरामीटर @whereand कहा जाता है, जो आंतरिक क्वेरी की जाती है कि टेबल लगाने के लिए इस्तेमाल किया जा रहा है (और एक AND साथ शुरू करना चाहिए) के WHERE खंड के साथ जोड़ दिया जाता है।

आप यह भी जानना वहाँ एक उपनाम, sysobjects के खिलाफ o, और sys.all_objects के खिलाफ एक दूसरे उर्फ ​​syso है कि है।

इस ज्ञान का उपयोग करना, आप अपने @whereand पैरामीटर शिल्प सकता है के रूप में:

EXEC sp_MSforeachtable 
@command1='...', 
@whereand='AND o.id in (select object_id from sys.columns c where c.name=''EMP_CODE'')' 

अब आप भी अपने command1 को आसान बनाने में कर सकते हैं, जब से तुम जानते हैं कि यह केवल एक EMP_CODE स्तंभ युक्त टेबल के खिलाफ चलाया जाएगा। मैं शायद COUNT(*) स्थिति भी ले जाऊंगा, क्योंकि मुझे नहीं लगता कि यह किस मूल्य को जोड़ रहा है।


अपने आगे काम के आधार पर अपडेट किया गया है, और एक मेज के खिलाफ परीक्षण किया:

DECLARE @EMPCODE AS VARCHAR(20) 
SET @EMPCODE='HO081' 
declare @sql nvarchar(2000) 
set @sql = ' 
    DECLARE @COUNT AS INT 
    SELECT @COUNT=COUNT(*) FROM ? WHERE EMP_CODE='''[email protected]+''' 
    IF @COUNT>0 
    BEGIN 
     PRINT PARSENAME("?",1)+'' => ''+CONVERT(VARCHAR,@COUNT)+'' ROW(S)'' 
     --PRINT ''DELETE FROM ''+PARSENAME("?",1)+'' WHERE EMP_CODE='''''[email protected]+''''''' 
    END 
' 
EXEC sp_MSforeachtable 
@[email protected],@whereand='AND O.ID IN (SELECT OBJECT_ID FROM SYS.COLUMNS C WHERE C.NAME=''EMP_CODE'')' 

(मैं @whereand वापस लौट चुके हैं EMP_CODE के लिए क्वेरी करने के लिए, जब से तुम वहाँ मूल्य को बदलने के लिए नहीं करना चाहते हैं)।

मुद्दा यह है कि, आप एक संग्रहीत प्रक्रिया के लिए मापदंडों, या शाब्दिक पारित कर सकते हैं, लेकिन आप गणना नहीं कर सकता/उन दोनों के बीच कार्यों के संयोजन है - तो मैं एसक्यूएल बयान के निर्माण के बाहर एक में चले गए अलग कार्रवाई

+4

आप दिखा आप क्या कर सकते हैं, लेकिन परोक्ष आपको बता ऐसा नहीं करने के लिए लिए +1;) – cairnz

+0

@Damien_The_Unbeliever मान लीजिए अगर मैं 'IF (COUNT का चयन करें (*) लिखने से कहां EMP_CODE = '' '+ @EMPCODE + '' ')> 0' तो यह मुझे क्यों दे रहा है - '+' के पास गलत वाक्यविन्यास। मैं एक चर के माध्यम से 'EMP_CODE' मान को पारित करने का प्रयास कर रहा हूं। –

+0

@ सोहमदासगुप्त - टिप्पणी अनुभाग में इस तरह के मुद्दे का निदान करना थोड़ा मुश्किल है, क्योंकि मुझे वास्तव में पूरी क्वेरी को देखना होगा क्योंकि यह अब खड़ा है, और यह टिप्पणियों में काम नहीं करेगा। मैं फिर से कोड के उस विशेष टुकड़े से पूछता हूं - क्यों * गिनती * मिलान करने की बजाए मिलान पंक्तियों की संख्या * क्यों? खाली परिणाम सेट आमतौर पर निपटने के लिए काफी आसान हैं। –

9

मुझे लगता है कि आपको किसी प्रकार की त्रुटि मिलती है, शायद Invalid column name 'EMP_CODE'?

ऐसा इसलिए है क्योंकि कॉलम की जांच करने से पहले कोड संकलित किया गया है। आप इसके बजाय ऐसा कर सकते हैं।

EXEC sp_MSforeachtable 
@command1=' 
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=PARSENAME("?",2) AND TABLE_NAME=PARSENAME("?",1) AND COLUMN_NAME="EMP_CODE") 
BEGIN 
    EXEC('' 
      IF (SELECT COUNT(*) FROM ? WHERE EMP_CODE="HO081")>0 
      BEGIN 
       SELECT * FROM ? WHERE EMP_CODE="HO081" 
      END 
     '') 
END 
' 
+0

महान काम करता है। धन्यवाद। –

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