SQL Server - 转换唯一标识符值为字符时结果空间不足

26

在从一个表复制数据到另一个表时,运行 SQL 查询时,我遇到了以下错误:

Msg 8170,Level 16,State 2,Line 2 Insufficient result space to convert uniqueidentifier value to char。

我的 SQL 查询是:

INSERT INTO dbo.cust_info (
uid,
first_name,
last_name
)
SELECT
NEWID(),
first_name,
last_name
FROM dbo.tmp_cust_info

我的建表脚本是:

CREATE TABLE [dbo].[cust_info](
    [uid] [varchar](32) NOT NULL,
    [first_name] [varchar](100) NULL,
    [last_name] [varchar](100) NULL)

CREATE TABLE [dbo].[tmp_cust_info](
    [first_name] [varchar](100) NULL,
    [last_name] [varchar](100) NULL)

我确定NEWID()存在问题,如果我将其取出并替换为某个字符串,则可以正常工作。

非常感谢任何帮助。提前致谢。

5个回答

40

因为需要加上破折号,所以 GUID 需要 36 个字符长度。而你只提供了 32 个字符的列,长度不够,因此导致错误。


7
顺便提一下,你应该使用 uniqueidentifier 列类型来存储 GUID,而不是 character(36)(既然它不是变量,就不需要 var 了,对吧?)。uniqueidentifier 只需要 16 字节的存储空间,而字符表示法需要 36 字节。 - Remus Rusanu
简单而直接的回答。 - bot

7

你需要使用以下三种方法之一:

1、使用uniqueidentifier列,它在内部存储为16个字节。当你从这个列中选择时,它会自动以8-4-4-4-12的格式呈现 用于显示

CREATE TABLE [dbo].[cust_info](
    [uid] uniqueidentifier NOT NULL,
    [first_name] [varchar](100) NULL,
    [last_name] [varchar](100) NULL)

2,不建议将字段更改为char(36),以便其符合格式,包括破折号。

CREATE TABLE [dbo].[cust_info](
    [uid] char(36) NOT NULL,
    [first_name] [varchar](100) NULL,
    [last_name] [varchar](100) NULL)

3,不推荐将其存储为没有破折号的32个字符组件。

INSERT INTO dbo.cust_info (
uid,
first_name,
last_name
)
SELECT
replace(NEWID(),'-',''),
first_name,
last_name
FROM dbo.tmp_cust_info

6

在进行GUID的简单字符串连接时,我收到了以下错误。显然,VARCHAR太小了。

我不得不更改:

SET @foo = '旧 GUID:{'+ CONVERT(VARCHAR, @guid) +'}';

改为:

SET @foo = '旧 GUID:{'+ CONVERT(NVARCHAR(36), @guid) +'}';

...然后一切都好了。非常感谢之前回答过这个问题的人!


2
你可以尝试这个方法。这个对我有效。
当你转换数值时,为VARCHAR指定长度。 对于唯一标识符,请使用以下的VARCHAR(36):
SELECT Convert (varchar(36),NEWID()) AS NEWID

如果我们在CAST / CONVERT期间没有指定长度,则VARCHAR数据类型的默认长度为30。
来源:Krishnakumar S
参考资料:https://social.msdn.microsoft.com/Forums/en-US/fb24a153-f468-4e18-afb8-60ce90b55234/insufficient-result-space-to-convert-uniqueidentifier-value-to-char?forum=transactsql

这解决了我的问题,我试图将@TraceId参数传递给存储过程以便在没有错误的情况下启用信息记录。一旦我将其更新为varchar(36),我的问题就得到了解决。然而,最初我忘记了将顶层参数@TraceId output也更新为varchar(36),所以它最初在我的日志中被截断了。别忘了更新所有的引用,否则可能会出现意外的结果哈哈。 - nulltron

2

将uid列的长度从varchar(32)增加到varchar(36),因为guid需要36个字符 Guid.NewGuid().ToString() -> 36个字符 输出:12345678-1234-1234-1234-123456789abc


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接