2012-08-30 18 views
7

के माध्यम से एसक्यूएल से बाइनरी फ़ाइल डेटा (छवियों) का निर्यात करना मैं एक बड़ी संख्या में छवि फ़ाइलों को निर्यात करने की कोशिश कर रहा हूं, जो आंतरिक रूप से SQL डेटाबेस में बाइनरी डेटा के रूप में संग्रहीत हैं।एक संग्रहीत प्रक्रिया

एसक्यूएल में संग्रहीत प्रक्रियाओं को लिखने के लिए काफी नया होने के नाते, मैं कुछ उपयोगी मार्गदर्शिकाओं में आया हूं कि इसे कैसे संग्रहीत किया जा सकता है, लेकिन मुझे कुछ याद आ रहा है।

मैं स्थानीय रूप से SQL Server 2008 R2 चला रहा हूं, और मैं फ़ाइलों को अपने सी: \ ड्राइव पर किसी फ़ोल्डर में लिखने की कोशिश कर रहा हूं।

यहाँ मैं अब तक राशि का व्यापार हिस्सा है:

BEGIN 
DECLARE @cmd VARCHAR(8000) 
DECLARE @result int 

DECLARE curExportBinaryDocs CURSOR FAST_FORWARD FOR 
SELECT 'BCP "SELECT Photograph_Data FROM [ALBSCH Trial].[dbo].[Photograph] WHERE Photograph_ID = ' 
    + CAST(Photograph_ID AS VARCHAR(500)) + '" queryout "' + @OutputFilePath 
    + CAST(Photograph_ID AS VARCHAR(500)) + '.jpg"' + ' -n -T' 
FROM dbo.Photograph 

OPEN curExportBinaryDocs 
FETCH NEXT FROM curExportBinaryDocs INTO @cmd 
WHILE @@FETCH_STATUS = 0 
    BEGIN 
    --PRINT @cmd 
    EXEC @result = xp_cmdshell @cmd   
    FETCH NEXT FROM curExportBinaryDocs INTO @cmd 
    END 
CLOSE curExportBinaryDocs 
DEALLOCATE curExportBinaryDocs 
END 

'@result' हमेशा '1' के लिए सेट किया जा रहा है (विफल) xp_cmdshell कॉल के बाद। सभी टेबल नाम/फ़ील्ड सही हैं, इसलिए मुझे संदेह है कि मेरे बीसीपी कॉल में कुछ गड़बड़ है, लेकिन मुझे यकीन नहीं है कि आगे क्या प्रयास करना है।

कोई भी मदद या सलाह का स्वागत किया जाएगा।

+0

आप SQL कैसे चला रहे हैं? एसक्यूएल उपयोगकर्ता के क्रेडेंशियल्स के तहत चलता है ... क्या उस उपयोगकर्ता को आउटपुट फ़ोल्डर में फाइलें बनाने का अधिकार है? –

+0

मैं अपने सामान्य विंडोज उपयोगकर्ता नाम और विंडोज प्रमाणीकरण का उपयोग कर SQL सर्वर में लॉग इन कर रहा हूं। मैंने यहां उल्लिखित विधि का उपयोग करके एक समाधान प्राप्त करने में कामयाब रहा है: http://stackoverflow.com/questions/1366544/how-to-export-image-field-to-file लेकिन यदि संभव हो तो मैं प्राप्त करना चाहता हूं समस्या के निचले हिस्से में मैं अपनी मूल विधि के साथ बस मन की शांति के लिए हूं! – ChrisMurray

+0

मेरा मानना ​​है कि आप जो कर रहे हैं वह थोड़ा गलत है। क्या आप SQL सर्वर के "फ़ाइल-स्ट्रीम सक्षम डेटाबेस" के बारे में जानते हैं। यह आपको हार्ड ड्राइव पर बीएलओबी स्टोर करने की अनुमति देता है जबकि बीएलओबी अभी भी आपके SQL सर्वर द्वारा बनाए रखे जाते हैं। इस बीएलओबी को ड्राइव पर फेंकने के बाद, आपके एप्लिकेशन को केवल आपके डेटाबेस में एक क्वेरी बनाने और ऑब्जेक्ट प्राप्त करने की आवश्यकता है। इसके अलावा, कर्सर का उपयोग करना अच्छी बात नहीं है (यह धीमा है)। – gotqn

उत्तर

5

ठीक है, सब .. की पहली (और अत: क्षमा करें;)) डॉन "टी उपयोग कर्सर .. और खेद टोपियां के लिए ...

कर्सर के बारे में सबसे baddest बातों में से एक यह है कि कर रहे हैं वे अपनी मेज लॉक कर सकते हैं। क्या मैं हमेशा इन उद्देश्यों के लिए करते हैं (और जो काफी तेजी से किया जाता है), मैं पाश के लिए एक का उपयोग .. इस

declare @totrow int 
     , @currow int 
     , @result int 
     , @nsql nvarchar(max) 

declare @sqlStatements table (
    Id int identity(1, 1) 
, SqlStatement varchar(max) 
) 
insert 
into @sqlStatements 
select 'QUERY PART' 
from table 

set @totrow = @@rowcount 
set @currow = 1 
while @totrow > 0 and @currow <= @totrow 
begin 
    select @nsql = SqlStatement 
    from @SqlStatements 
    where Id = @currow 

    exec @result = xp_cmdshell @nsql 

    set @currow = @currow + 1 
end 

अगले भाग के लिए की तरह, एसक्यूएल सर्वर प्रक्रिया के लिए पर्याप्त अनुमति नहीं है करता है सी: ड्राइव को लिखें? इसके अलावा, जब आप अपना कोड निष्पादित करते हैं तो अपने संदेश फलक में देखें, शायद आप वहां कुछ पा सकते हैं?

आप क्या कर सकते हैं, इसे मैन्युअल रूप से निष्पादित करने का प्रयास करें। बस एक बीसीपी कथन प्राप्त करें और इसे xp_cmdshell के साथ निष्पादित करें। क्या यह कोई त्रुटि देता है?

+0

धन्यवाद मार्क मैं काम करने के लिए एक अलग समाधान प्राप्त करने के बाद से इस पर आगे बढ़ गया था, लेकिन आपकी टिप्पणियां देखकर मैं गया और एक और नजर डाला। कर्सर का उपयोग करने से बचने के लिए मेरे कोड को संशोधित करने के बाद और फिर बीसीपी अनुमतियों और उद्धरण चिह्न विषमता के साथ कुश्ती के बाद, अब मैं ठीक काम कर रहा हूं! बहुत धन्यवाद। मैं आपकी प्रतिक्रिया को वोट दूंगा, लेकिन मेरे पास अभी तक पर्याप्त प्रतिनिधि नहीं हैं :) – ChrisMurray

+0

यह सुनकर अच्छा लगा :) –

+0

@MarkKremers जब आप सही कर्सर खराब होते हैं, तो आप पाएंगे जबकि लूप को कर्सर के माध्यम से कार्यान्वित किया जाता है, और कर्सर प्रदान करते हैं प्रदर्शन पर अधिक नियंत्रण, इसलिए जबकि लूप उचित कर्सर से बेहतर प्रदर्शन करते हैं: http://sqlblog.com/blogs/aaron_bertrand/archive/2012/01/26/the-fallacy-that-a-while-loop-isn-ta- cursor.aspx – ConstantineK

6

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

CREATE PROCEDURE [dbo].[ImgExport] 
    @OutputFilePath VARCHAR(500) = 'C:\SQLTest\ ' 
AS 
BEGIN 
    DECLARE @totrow int 
    DECLARE @currow int 
    DECLARE @result int 
    DECLARE @nsql nvarchar(4000) 
    DECLARE @sqlStatements table (ID int IDENTITY(1, 1), SqlStatement varchar(max)) 

    INSERT 
    INTO @sqlStatements 
    SELECT 'BCP "SELECT Photograph_Data FROM [ALBSCH_Trial].[dbo].[Photograph] WHERE Photograph_ID = ''' 
    + CAST(Photograph_ID AS VARCHAR(500)) + '''" queryout ' + @OutputFilePath 
    + CAST(Photograph_ID AS VARCHAR(500)) + '.jpg -S localhost\SQLEXPRESS2008 -T -f C:\SQLTest\Images.fmt' 
    FROM dbo.Photograph 

    SET @totrow = @@ROWCOUNT 
    SET @currow = 1 
    WHILE @totrow > 0 and @currow <= @totrow 
    BEGIN 
     SELECT @nsql = SqlStatement 
     FROM @sqlStatements 
     WHERE ID = @currow 
     EXEC @result = xp_cmdshell @nsql 
     SET @currow = @currow + 1 
    END 
END  

स्वरूप फ़ाइल:

9.0 
1 
1  SQLBINARY  0  0  "\t"  1  Photograph_Data         "" 

मुझे आशा है कि किसी को मदद मिलती है।

+1

हाय, @ChrisMurray, चूंकि इस कॉलम की सामग्री द्विआधारी/कच्ची डेटा है, इसलिए आप बीसीपी कमांड लाइन में '-N' ध्वज प्रदान करके स्वरूपण फ़ाइल से बच सकते हैं, यानी: 'बीसीपी" से डेटा चुनें [ फोटोग्राफ] जहां आईडी = 123; " पूछताछ "123.jpg" -S localhost \ SQLEXPRESS2008 -T -N' –

+0

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

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