【问题标题】:Storing VARBINARY in a VARCHAR column将 VARBINARY 存储在 VARCHAR 列中
【发布时间】:2019-02-15 05:42:55
【问题描述】:

请通过此代码:

DECLARE @EncryptedPassword VARBINARY(8000) = ENCRYPTBYPASSPHRASE('ABCD','password')
DECLARE @Setting AS TABLE (ID INT, Value VARCHAR(MAX))

INSERT INTO @Setting VALUES (1, 'true')
INSERT INTO @Setting VALUES (2, @EncryptedPassword)

SELECT * FROM @Setting

@Setting 表可以包含多种数据类型的数据。正如我所看到的,它存储了价值。但无法使用SELECT 命令检索它。我怎样才能做到这一点?

【问题讨论】:

  • CONVERT(VARCHAR(MAX), @EncryptedPassword, 2) 会给你一个十六进制字符串,可以用同样的方式转换回来。
  • 请重新考虑这个设计。使所有内容字符串 输入会使事情“更简单”,直到您检索到一个应该int(或者这里是varbinary)的设置并且您找到一些那里完全不合适的字符串。考虑将您的个人设置改为

标签: sql-server varbinary


【解决方案1】:

正如我在 cmets 中所说,我强烈建议您调整设置表并停止输入所有内容:

DECLARE @EncryptedPassword VARBINARY(8000) = ENCRYPTBYPASSPHRASE('ABCD','password')
DECLARE @Setting AS TABLE (
    Lock char(1) not null default 'X' primary key check (Lock='X'),
    SomethingBoolean bit not null,
    Password varbinary(8000) not null)

INSERT INTO @Setting (SomethingBoolean, Password) VALUES
(1,@EncryptedPassword)

SELECT * FROM @Setting

结果:

Lock SomethingBoolean Password
---- ---------------- -----------------------------------------------------------------------------------------------------------
X    1                0x02000000588C2EB2C67DED10B7828C05500008DB1B1E53EFF63168EC607CA80CA2A1147B75F0A9D50F6B95C810D6DCED37AE8186

这意味着设置实际上是以正确的数据类型存储的。我们不仅可以依靠类型和空值检查来确保设置正确,还可以根据需要对单个设置应用单个 CHECK 约束。

Lock 只是为了确保此表仅包含 1 行)

【讨论】:

    【解决方案2】:

    尝试更改表结构并在检索 DECRYPT 值时尝试转换为 Varbinary 列 Nvarchar.ENCRYPTBYPASSPHRASE 或 DECRYPTBYPASSPHRASE 需要 2 个或更多参数才能为您提供结果

    DECLARE @Setting AS TABLE (ID INT,Value VARBINARY(8000))
    
    INSERT INTO @Setting 
    SELECT 1,ENCRYPTBYPASSPHRASE('password',N'ABCD')
    
    SELECT * FROM @Setting
    SELECT CONVERT(NVARCHAR(4000),DECRYPTBYPASSPHRASE('password',Value)) FROM @Setting
    

    【讨论】:

      【解决方案3】:

      你可以只添加加密标志:

      DECLARE @EncryptPhrase NVARCHAR(100) = 'ABCD'
      
      DECLARE @Setting AS TABLE (ID INT, Value NVARCHAR(MAX), IsEncrypted BIT)
      
      INSERT INTO @Setting VALUES (1, 'true',  0)
      INSERT INTO @Setting VALUES (2, ENCRYPTBYPASSPHRASE(@EncryptPhrase,N'password'), 1)
      
      SELECT * FROM @Setting
      
      SELECT 
      ID
      ,CASE 
          WHEN IsEncrypted = 1 THEN CAST(DecryptByPassPhrase(@EncryptPhrase, CAST(Value AS VARBINARY(MAX))) as NVARCHAR(MAX)) 
          ELSE Value 
      END
      FROM @Setting
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-10
        • 2010-11-01
        相关资源
        最近更新 更多