sql server - XP_CMDSHELL से परिणाम प्राप्त करें




sql-server stored-procedures (2)

xp_cmdshell से STDOUT / STDERR फ़ीडबैक पर कब्जा करने का कोई आसान तरीका नहीं है; कम से कम एक विकल्प है लेकिन इसे आसानी से वर्गीकृत नहीं किया जा सकता है:
कमांड के हिस्से के रूप में कमांड के आउटपुट को एक पाठ फ़ाइल में पुनर्निर्देशित करना संभव होगा, फिर OPENROWSET का उपयोग करके पाठ फ़ाइल पढ़ें।

बीटीडब्लूडब्लूटीपी में लिखित स्क्रिप्ट में कम से कम एक त्रुटि है। xp_cmdshell लिए दस्तावेज़ यह बताते हैं कि यह कमांड आउटपुट को नववर्कर (255) के रूप में देता है।
साथ ही, अस्थायी तालिका में एक पहचान कॉलम होना चाहिए, अन्यथा परिणाम सही क्रम में प्रदर्शित नहीं किए जा सकते हैं:

...
create table #output (id int identity(1,1), output nvarchar(255) null)
insert #output (output) exec @rc = master..xp_cmdshell @cmd
select * from #output where output is not null order by id
drop table #output

मैं कुछ वेब खोज कर रहा हूं और ऐसा लगता है कि XP_CMDSHELL से परिणाम प्राप्त करने का एकमात्र तरीका उन्हें एक अस्थायी तालिका में स्टोर करना है। वास्तव में कोई आसान तरीका नहीं है?

एक्सचेंज एक्सचेंज से:

नहीं, xp_cmdshell exe से कोई भी जानकारी वापस नहीं करेगा। और आपको निम्न सिंटैक्स का उपयोग करना होगा यदि आप इसे चलाने के लिए मास्टर डेटाबेस में नहीं हैं। master..xp_cmdshell। मास्टर डेटाबेस में इस प्रक्रिया को निष्पादित करने के लिए आपको अपने उपयोगकर्ता की अनुमति देना होगा। आपको अपने exe को जानकारी स्वयं को सम्मिलित करना पड़ेगा क्योंकि यह उस प्रक्रिया को जानकारी नहीं लौटा सकता है जिसे इसे कहा जाता है।

तथा...

जबकि @ श्रेणी केवल xp_cmdshell से रिटर्न मान हो जाता है, आप सीधे तालिका में डालने से कमांड के परिणामों को कैप्चर कर सकते हैं ... ऐसा कुछ:

YMMV ...

set nocount on
declare  @filepath   varchar(255),
         @cmd        varchar(255),
         @rc         int

select   @filepath = 'c:\temp\'         
select   @cmd      = 'dir ' + @filepath + '~*.tmp'

create table #output (output varchar(255) null)
insert #output exec @rc = master..xp_cmdshell @cmd
select * from #output where output is not null
drop table #output

यह वही है जो मैंने समाप्त कर दिया ... मैंने आज की जाँच की और आपकी प्रतिक्रिया देखी। मैं कल एक वास्तविक समय की कमी में था अतः अस्थायी तालिका की दिशा में काम करना शुरू कर दिया था क्योंकि यह एक पुष्टि कार्य समाधान था। मैंने अस्थायी फाइलों को बनाने से बचने के लिए चुना था क्योंकि यह वास्तव में चीजों को आंतरिक रूप से संभालना आसान और सरल लग रहा था क्योंकि मैं वास्तव में एक क्लिपबोर्ड के रूप में इसका प्रयोग कर रहा हूं। यदि आवश्यक हो तो एक बदलाव मैं अस्थायी तालिका नाम के लिए एक अनन्य संख्या जोड़ना चाहता हूं, हालांकि मुझे नहीं लगता है कि मुझे इसके बारे में एक साथ संसाधित होने की चिंता है (जिसका अर्थ है कि संग्रहीत कार्यविधि का दूसरा कॉलम अस्थायी तालिका को डंप कर सकता है सीएमडी खोल चल रहा है)। हम देखेंगे...

पासवर्ड को एन्क्रिप्ट करने के लिए मैं एक संग्रहीत कार्यविधि (आगे नीचे देखें) को कॉल करता हूं: नीचे दिए गए कोड को आत्मनिर्भर बनाने के लिए संशोधित किया गया है। मैं वास्तव में पासवर्ड मैन्युअल रूप से सेट नहीं कर रहा हूँ क्योंकि यह मूल रूप से एक पासवर्ड ऑफलोडिंग / सिंक्रनाइज़ेशन समाधान है।

DECLARE @password       VARCHAR(64)
DECLARE @encryptedpass  VARCHAR(128);

SET @password = '1234'

BEGIN TRY
    EXEC pass_encrypt @password, @encryptedpass = @encryptedpass OUTPUT
END TRY
BEGIN CATCH
    PRINT 'ERROR'
    RETURN
END CATCH
SELECT @encryptedpass

यहां संग्रहीत कार्यप्रणाली एन्क्रिप्ट कर रही है: जांचने और सुनिश्चित करने के लिए कि प्रोग्राम को विफल किए बिना ठीक से निष्पादित होने के कारण, रिटर्न कोड विफलता को इंगित करता है, मेरे पास अतिरिक्त कोड है (यहां सूचीबद्ध नहीं है) जो @@ रोवेट की जांच करता है यदि यह 1 से ज्यादा है, तो मुझे पता है कि कुछ गलत हो गया है और मैं अपने खुद के संदेश को बनाने के बजाय वास्तविक त्रुटि (अगर वांछित) को वापस / वापस कर सकता / सकती हूं, जिसके कारण कोई भी संकेत दिए बिना इसे विफल कर दिया गया है। वास्तविक रूप से इस तरह की जांच करना डीबगिंग के लिए या भविष्य की समीक्षा के लिए किसी अन्य तालिका में त्रुटि के लिए प्रवेश करने के लिए अधिक उपयोगी है - वास्तविक समय की व्याख्या के लिए नहीं क्योंकि मैं एक अंत उपयोगकर्ता को वापस एक त्रुटि भेजने नहीं जा रहा हूं।

USE [**my_database**]
GO

SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO


CREATE procedure [dbo].[pass_encrypt]
(   @password       VARCHAR(64),
    @encryptedpass  VARCHAR(128) OUTPUT
)
AS
BEGIN
    DECLARE @command        VARCHAR(200)
    SET @command = **'C:\encrypt_pwd.exe**' + ' "' + @password + '"'

    BEGIN
        IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[#temppass]') AND type in (N'U')) 
            DROP TABLE [dbo].[#temppass]
        BEGIN TRY
            CREATE TABLE #temppass(encrypted varchar(1000))
            INSERT INTO #temppass execute xp_cmdshell @command
            IF (@@ROWCOUNT > 1)
                BEGIN
                    SET @encryptedpass = NULL
                    DROP TABLE #temppass
                    RETURN
                END
            ELSE
                BEGIN
                    SELECT @encryptedpass = encrypted FROM #temppass
                END
            --SELECT @encryptedpass
        END TRY
        BEGIN CATCH
            SET @encryptedpass = NULL
            DROP TABLE #temppass
            RETURN
        END CATCH
        --SELECT encrypted FROM #temppass
        DROP TABLE #temppass
    END
END




xp-cmdshell