为什么SQL Server程序将Guid作为字符串读取?

问题描述 投票:0回答:2

我有这个存储过程:

ALTER PROCEDURE [dbo].[_Doc_GetDoc]
    @Id uniqueidentifier
AS  
BEGIN
    DECLARE @RetVal INT,
            @TranCount INT

BEGIN TRY
    IF (ISNUll(@Id, '') = '')
        RETURN 1002
    ELSE
    BEGIN
        SELECT .....
        FROM Documents WITH (nolock)        
        WHERE Documents.Id = @Id 
          AND ISNULL(Documents.IsDeleted, 0) = 0

        SET @RetVal = 1
    END
END TRY
BEGIN CATCH
    PRINT error_message()
    SET @RetVal= 9999   
END CATCH

RETURN @RetVal
END

当我像这样运行它:

USE [xxxxxxxx]
GO

DECLARE @return_value int

EXEC    @return_value = [dbo].[_Doc_GetDoc]
        @Id = 6666a6c6-6666-e966-67a9-a5bf52222d44

SELECT  'Return Value' = @return_value

GO

我收到此错误:

Msg 102,Level 15,State 1,Line 7 '6666a6c6'附近的语法不正确。

如果我用单引号传递@Id,它会说Conversion failed when converting from a character string to uniqueidentifier

我试过了:

exec [dbo].[_Doc_GetDocument] '6666a6c6-6666-e966-67a9-a5bf52222d44'
exec [dbo].[_Doc_GetDocument] @DocId='6666a6c6-6666-e966-67a9-a5bf52222d44'

但同样的错误:从字符串转换为uniqueidentifier时转换失败。

sql-server
2个回答
1
投票

你的失败在这里:

  if(ISNUll(@Id,'')='')

如果将引用引用参数传递给isnull,则输入(第一个参数)将被视为字符串。试试这个:

编辑:

if @Id IS NULL

更多,我注意到你的alter procedure正在调用[dbo].[_Doc_GetDoc],但你尝试执行exec [dbo].[_Doc_GetDocument]。确保你正在调用正确的,并使用正方形代替引号作为你的ID参数:

exec [dbo].[_Doc_GetDoc] [6666a6c6-6666-e966-67a9-a5bf52222d44]

1
投票

uniqueidentifier数据类型具有比字符类型更高的precedence,因此SQL Server将在此比较操作期间尝试将字符值转换为uniqueidentifier:

where Documents.Id=@Id

如果Id列包含无法转换的值,则操作将失败并出现转换错误。例如:

SELECT 'oops' 
WHERE CAST('6666a6c6-6666-e966-67a9-a5bf52222d44' AS uniqueidentifier) = 'foobar';

所以看起来你在表中有无效的GUID字符串值。最佳实践是将列数据类型更改为uniqueidentifier以避免问题继续进行。这将要求修复现有的不良数据。

© www.soinside.com 2019 - 2024. All rights reserved.