尝试从数据库下载“图像”列内容时出现日期类型转换错误

Posted

技术标签:

【中文标题】尝试从数据库下载“图像”列内容时出现日期类型转换错误【英文标题】:Datetype conversion error when trying to download 'image' column contents from database 【发布时间】:2018-08-13 05:33:12 【问题描述】:

我正在尝试下载存储在数据库表中的所有文件/文档。表结构如下:

CREATE TABLE [dbo].[eAttachment](
    [eKey] [nvarchar](250) NOT NULL,
    [eSize] [int] NULL,
    [eContents] [image] NULL,
 CONSTRAINT [ePKU_eAttachment] PRIMARY KEY CLUSTERED 
(
    [eKey] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

典型内容:

esize: 173586
ekey: 0 0000000000000000000000000005010 Filename.pdf
econtents: 0x7B00350030000037003500460030002D003400310046....etc

我尝试使用的 SQL 在第 30 行失败(在下面标有注释),并出现以下错误。

(受影响的 5 行)

(受影响的 5 行)

消息 8114,第 16 级,状态 5,第 30 行

将数据类型 varchar 转换为 bigint 时出错。

这是完整的代码

DECLARE @outPutPath varchar(100)
, @i bigint
, @init int
, @econtents varbinary(max) 
, @fPath varchar(max)  
, @folderPath  varchar(max) 
, @efolderName nvarchar(31)
, @ekey nvarchar(250)

DECLARE @Doctable TABLE (id bigint identity(1,1), ekey  nvarchar(250) , esize int, [econtents] varbinary(max) )

INSERT INTO @Doctable([ekey] , [esize],[econtents])
Select top 5 ekey, esize, econtents from eattachment
select * from @doctable

SELECT @i = COUNT(1) FROM @Doctable

WHILE @i <= 5
BEGIN 

    SET @ekey = (SELECT STUFF(LEFT(ekey,33),1,1,'') from @doctable where id = @i)
    SET @efoldername =  (select top 1 efoldername
                                    from efolder 
                                    where efolderid 
                                    like @ekey
                                    )
    SET @outPutPath = '\\location\to\store\files'

    SELECT --fails here
     @econtents = [econtents],
     @fPath = @outPutPath + '\'+ [id] + '\' + @efolderName + '\' + RIGHT(ekey, LEN(ekey) - 33), 
     @folderPath = @outPutPath + '\'+ [id]
    FROM @Doctable WHERE id = @i

  EXEC  [dbo].[CreateFolder]  @folderPath
  EXEC sp_OACreate 'ADODB.Stream', @init OUTPUT; 
  EXEC sp_OASetProperty @init, 'Type', 1;  
  EXEC sp_OAMethod @init, 'Open'; 
  EXEC sp_OAMethod @init, 'Write', NULL, @econtents; 
  EXEC sp_OAMethod @init, 'SaveToFile', NULL, @fPath, 2; 
  EXEC sp_OAMethod @init, 'Close'; 
  EXEC sp_OADestroy @init; 

  print 'Document saved to: '+  @fPath   

SELECT @econtents = NULL  
, @init = NULL
, @fPath = NULL  
, @folderPath = NULL
SET @i = 1
END

为什么它会因该错误而失败?我希望它只是将文件复制到我的文件夹中。

我看不到任何 varchar->bigint 转换正在发生,尤其是在它说它失败的那一行。

我怀疑这与源表中的 image 和临时表中的 varbinary 类型的 econtents 列有关。 SQL 告诉我不允许在过程/声明变量中使用image,所以我认为它会自动转换?

编辑:这与其他帖子无关,因为这是日期时间转换问题。有人已经发布了一个有效的答案,但他们已将其删除

【问题讨论】:

仅供参考:Data Type Precedence. 不是重复的。 问题是数据类型优先级问题,如副本所示。 [id] 的数据类型为BigInt。当它与字符串类型一起在表达式中使用时,它会导致字符串转换为BigInt,如data type precendence 的文档中所述。由于连接到@fpath 的其他一些表达式不包含有效的数字数据,因此您会得到“将数据类型 varchar 转换为 bigint 时出错”的奖励。将[id] 转换为字符串:Cast( [id] as VarChar(16) ) 很好。还是修好了 我仍然认为它是重复的,但是由于有人(或某些人)重新打开它,我已经取消删除我的答案。请检查它是否解决了您的问题。 【参考方案1】:

这是你的问题:

 @fPath = @outPutPath + '\'+ [id] + '\' + @efolderName + '\' + RIGHT(ekey, LEN(ekey) - 33), 
 @folderPath = @outPutPath + '\'+ [id]

在将字符串连接到 bigint 时,SQL Server 将尝试将字符串隐式转换为 bigint 和 sum 而不是 concat,除非您将 bigint 显式转换为字符串数据类型。

改成

 @fPath = @outPutPath + '\'+ CAST([id] as varchar(21)) + '\' + @efolderName + '\' + RIGHT(ekey, LEN(ekey) - 33), 
 @folderPath = @outPutPath + '\'+ CAST([id] as varchar(21))

(您需要 21 个字符,因为 bigint 的最小值有 20 个数字和一个减号)。

【讨论】:

仅供参考:Data Type Precedence. @Habo 请发表您对该问题的评论,因为我想删除我的答案,因为它是重复的。

以上是关于尝试从数据库下载“图像”列内容时出现日期类型转换错误的主要内容,如果未能解决你的问题,请参考以下文章

PySpark:将String类型的DataFrame列转换为Double时出现KeyError

转换日期时出现异常

尝试将分类特征转换为数值时出现“ValueError:给定列不是数据框的列”

使用 Batik 将 svg 转换为图像时出现 TranscoderException

从监督学习数据集中删除列时出现奇怪的值

使用 OpenCV 从 android Camera2 将 YUV 转换为 RGB ImageReader 时出现问题,输出图像为灰度