OLE程序,查询成功执行;没有提取文件

时间:2018-04-08 13:50:43

标签: sql sql-server

我正在尝试从SQL Server中提取blob文件。我能够让它成功执行但当我查看我的Desktop \ consol \ output目录时,文件不存在(刷新,仍然没有)。这是代码:

SELECT * FROM FileWarehouse

sp_configure 'show advanced options', 1;  
GO  
RECONFIGURE;  
GO  
sp_configure 'Ole Automation Procedures', 1;  
GO  
RECONFIGURE;  
GO  


DECLARE @SQLIMG VARCHAR(MAX),
        @File VARBINARY(MAX), 
        @OpPath VARCHAR(MAX),
        @ObjectToken INT 


SELECT     @File = StoredFile FROM [dbo].[FileWarehouse] WHERE Id= 157994
SET        @OpPath = 'C:\Users\Nick\Desktop\consol\output\marksheet.doc'
EXEC       sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT 
EXEC       sp_OASetProperty @ObjectToken, 'Type', 1
EXEC       sp_OAMethod @ObjectToken, 'Open' 
EXEC       sp_OAMethod @ObjectToken, 'Write', NULL, @File 
EXEC       sp_OAMethod @ObjectToken, 'SaveToFile', NULL, @OpPath, 2
EXEC       sp_OAMethod @ObjectToken, 'Close'
EXEC       sp_OADestroy @ObjectToken
GO

在SELECT语句中,dbo。[FileWarehouse]和StoredFile都带有下划线,分别表示“Invalid Object Name”和“Invalid Column Name”。它们肯定是有效的,所以我不确定它是这么说的。这是我关注https://www.youtube.com/watch?v=8g7_F3Ice6E的教程。

非常感谢任何帮助。谢谢。

2 个答案:

答案 0 :(得分:1)

虽然Dan的答案是正确的(使用Powershell或SQL CLR代替),但是COM自动化不起作用的原因是您无法捕获并检查扩展存储过程的返回代码。

以下是一个例子:

--exec sp_configure 'Show Advanced Options', 1
--reconfigure 
--exec sp_configure 'Ole Automation Procedures', 1
--reconfigure

declare @url varchar(2000) = 'http://www.bing.com'

declare @hr int;
declare @win int;

begin try

  EXEC @hr=sp_OACreate 'WinHttp.WinHttpRequest.5.1',@win OUT 
  IF @hr <> 0 EXEC sp_OAGetErrorInfo @win 

  EXEC @hr=sp_OAMethod @win, 'Open',NULL,'GET',@url,'false'
  IF @hr <> 0 EXEC sp_OAGetErrorInfo @win 

  EXEC @hr=sp_OAMethod @win,'Send'
  IF @hr <> 0 EXEC sp_OAGetErrorInfo @win 

  declare @status int
  EXEC @hr=sp_OAGetProperty @win,'Status', @status out
  IF @hr <> 0 EXEC sp_OAGetErrorInfo @win

  if @status <> 200
  begin;
    declare @msg varchar(2000) = concat('web request failed ', @status);
    throw 60000, @msg, 1;
  end;

  declare @response table(text nvarchar(max));

  insert into @response(text)
  EXEC @hr=sp_OAGetProperty @win,'ResponseText';
  IF @hr <> 0 EXEC sp_OAGetErrorInfo @win;

  select * from @response;

  EXEC @hr=sp_OADestroy @win 
  IF @hr <> 0 EXEC sp_OAGetErrorInfo @win;

end try
begin catch

  EXEC @hr=sp_OADestroy @win 
  IF @hr <> 0 EXEC sp_OAGetErrorInfo @win;
  throw;

end catch

答案 1 :(得分:0)

如果脚本运行,则IntelliSense错误是错误的。

我建议你一般避免新开发的ole自动化过程。如果您不需要使用T-SQL创建文件,请考虑使用简单的PowerShell脚本。这对于临时需求更加强大和灵活。下面是一个使用标准ADO.NET对象的示例。

$connection = New-Object System.Data.SqlClient.SQLConnection("Data Source=YourServer;Initial Catalog=YourDatabase;Integrated Security=SSPI")
$command = New-Object System.Data.SqlClient.SqlCommand("SELECT StoredFile FROM [dbo].[FileWarehouse] WHERE Id= 157994;", $connection)
$connection.Open()
$blob = $connection.ExecuteScalar()
$connection.Close()
[System.IO.File]::WriteAllBytes("C:\Users\Nick\Desktop\consol\output\marksheet.doc", $blob)