这一年是2010年。
SQL Server许可证并不便宜。
然而,此错误仍未指示 行 或 列 或产生问题的值 。好吧,它甚至不能告诉你它是“字符串”还是“二进制”数据。
我错过了什么吗?
答案 0 :(得分:17)
解决这些问题的快捷方法是将行选择到新的物理表中,如下所示:
SELECT * INTO dbo.MyNewTable FROM <the rest of the offending query goes here>
...然后将此表的模式与INSERT先前进入的表的模式进行比较 - 并查找更大的列。
答案 1 :(得分:2)
我意识到这是一个旧的。这是我使用的一小段代码有帮助。
这样做会返回您尝试从中选择的表中的最大长度表。然后,您可以将字段长度与每列返回的最大值进行比较,并找出导致问题的最大值。然后,它只是一个简单的查询来清理数据或将其排除。
DECLARE @col NVARCHAR(50)
DECLARE @sql NVARCHAR(MAX);
CREATE TABLE ##temp (colname nvarchar(50), maxVal int)
DECLARE oloop CURSOR FOR
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'SOURCETABLENAME' AND TABLE_SCHEMA='dbo'
OPEN oLoop
FETCH NEXT FROM oloop INTO @col;
WHILE (@@FETCH_STATUS = 0)
BEGIN
SET @sql = '
DECLARE @val INT;
SELECT @val = MAX(LEN(' + @col + ')) FROM dbo.SOURCETABLENAME;
INSERT INTO ##temp
( colname, maxVal )
VALUES ( N''' + @col + ''', -- colname - nvarchar(50)
@val -- maxVal - int
)';
EXEC(@sql);
FETCH NEXT FROM oloop INTO @col;
END
CLOSE oloop;
DEALLOCATE oloop
SELECT * FROM ##temp
DROP TABLE ##temp;
答案 2 :(得分:2)
这里的另一种方法是使用二进制搜索。
注释代码中的一半列,然后重试。如果错误仍然存在,请注释掉该半部分的另一半并再试一次。您最终会将搜索范围缩小到两列。
答案 3 :(得分:1)
您可以使用if条件检查每个插入值的长度,如果值需要的宽度大于当前列宽,则截断该值并抛出自定义错误。
如果您只需要确定哪个是导致问题的字段,这应该可行。我不知道有没有更好的方法来做到这一点。
答案 4 :(得分:1)
建议您投票支持Microsoft网站上的增强请求。它已经活跃了6年了,所以谁知道微软是否会做任何事情,但至少你可以成为一个吱吱作响的轮子:Microsoft Connect
答案 5 :(得分:1)
对于字符串截断,我想出了以下解决方案来查找所有列的最大长度:
1)选择临时表的所有数据(在需要时提供列名称),例如
SELECT col1
,col2
,col3_4 = col3 + '-' + col4
INTO #temp;
2)在同一连接中运行以下SQL语句(如果需要,调整临时表名):
DECLARE @table VARCHAR(MAX) = '#temp'; -- change this to your temp table name
DECLARE @select VARCHAR(MAX) = '';
DECLARE @prefix VARCHAR(256) = 'MAX(LEN(';
DECLARE @suffix VARCHAR(256) = ')) AS max_';
DECLARE @nl CHAR(2) = CHAR(13) + CHAR(10);
SELECT @select = @select + @prefix + name + @suffix + name + @nl + ','
FROM tempdb.sys.columns
WHERE object_id = object_id('tempdb..' + @table);
SELECT @select = 'SELECT ' + @select + '0' + @nl + 'FROM ' + @table
EXEC(@select);
它将返回一个结果集,其列名前缀为&#39; max _&#39;并显示每列的最大长度。
识别出错列后,您可以运行其他select语句来查找超长行并根据需要调整代码/数据。
答案 6 :(得分:0)
我真的想不出一个好方法。
我曾经花了很多时间调试一个非常有用的“分零”信息。
通常你会注释掉各种输出代码,以找出引起问题的输出代码
然后你拿这个你找到的那个并让它返回一个值,表示存在问题而不是实际值(在你的情况下,应该用len(of the output)
替换字符串输出)。然后手动比较要插入的列的长度。
答案 7 :(得分:0)
从错误消息中的行号,您应该能够识别导致错误的插入查询。将其修改为select查询,以便在查询中包含AND LEN(your_expression_or_column_here) > CONSTANT_COL_INT_LEN
字符串的各个列。看看输出,它会给你不好的行。
答案 8 :(得分:0)
从技术上讲,没有一行要指向,因为SQL没有将数据写入表中。我通常只是捕获跟踪,运行它查询分析器(除非问题已经从跟踪中显而易见,在这种情况下可能是这样),并从那里快速调试与旧的“修改我的UPDATE到SELECT”方法。它不是真的只分解为两件事之一:
a)您的列定义错误,需要更改宽度 b)您的列定义是正确的,应用程序需要更具防御性
答案 9 :(得分:0)
对我有用的最好的事情是使用select .... into #temptable将行首先放入临时表中 然后我获取了临时表中每列的最大长度。例如。选择max(len(jobid))作为Jobid,.... 然后将其与源表字段定义进行比较。