更新多个 WHERE SQL 不起作用 [关闭]
Posted
技术标签:
【中文标题】更新多个 WHERE SQL 不起作用 [关闭]【英文标题】:UPDATE multiple WHERE SQL not working [closed] 【发布时间】:2015-06-30 14:54:53 【问题描述】:我正在尝试运行查询以更新 DATA
表,其中 MAXNVQ
不同,它将在 Burnham Grade 列中更新不同的值。
这是我目前的代码:-
UPDATE Data
SET Data.BurnhamGrade = (CASE WHEN Data.[MAXNVQ] > 3 THEN 'Grade II/III'
WHEN Data.[MAXNVQ] = 3 THEN 'Grade IV'
WHEN Data.[MAXNVQ] < 3 THEN 'Grade IV' END)
WHERE (MAXNVQ > 3) OR
(MAXNVQ = 3) OR
(MAXNVQ < 3)
我收到一条错误提示 SQL Execution Error:
字符串或二进制数据将被截断语句已被 终止。
好像我的SQL一直出错
【问题讨论】:
并不是说这会解决任何问题,但是您可以完全摆脱where
子句。它什么也做不了。
嗯...您的条件始终为真(除非MAXNVQ
可以为空)。你想做什么?
我收到一条错误消息,提示 SQL 执行错误。字符串或二进制数据将被截断语句已终止。就像我在 SQL 中犯了一个错误
data.burnhamgrade 的数据类型是什么?
这只是说BurnhamGrade
列对于您要保存的数据来说不够大。也许只是varchar(8)
或其他什么?
【参考方案1】:
也许这应该是一个评论,但 cmets 似乎是关于其他主题的。您的查询(或同等查询)是:
UPDATE Data
SET Data.BurnhamGrade = (CASE WHEN Data.[MAXNVQ] > 3 THEN 'Grade II/III'
WHEN Data.[MAXNVQ] = 3 THEN 'Grade IV'
WHEN Data.[MAXNVQ] < 3 THEN 'Grade IV' END)
WHERE MAXNVQ IS NOT NULL;
如果您遇到数据截断错误,那是因为分配给Data.BurnhamGrade
的字符串对于该列来说太长了。所以,检查列的长度。
造成这种情况的一个常见原因是长度不在变量中。所以,如果你的表定义为:
CREATE TABLE data (
. . .
BurnhamData varchar,
. . .
);
这会为列分配一个默认长度,该长度取决于上下文,通常为“1”。没有错误,只是比您想要的短一列。而是:
CREATE TABLE data (
. . .
BurnhamData varchar(255),
. . .
);
或者,如果此映射始终为真,则将值存储在引用表中并使用JOIN
,或者,使用计算列:
ALTER TABLE data
ADD BurnhamGrade AS (CASE WHEN Data.[MAXNVQ] > 3 THEN 'Grade II/III'
WHEN Data.[MAXNVQ] = 3 THEN 'Grade IV'
WHEN Data.[MAXNVQ] < 3 THEN 'Grade IV'
END)
使用这种方法,您不必担心保持值是最新的。无论何时查询表并使用列都是正确的。
【讨论】:
谢谢你这工作完美:) 评论:我现在明确建议使用nvarchar(x)
,而不是varchar(x)
。 nvarchar
是 Unicode,这意味着每个字符 2 个字节,但您基本上可以存储来自世界上所有语言(甚至是中文等)的所有字符,而不会感到头疼。 varchar
是 8 位的,如果你想插入 äöüè 等字母,你会很头疼。时代变了。世界是圆的,cpu快,内存便宜。
@SQLPolice 并非所有的 unicode 都可以存储在 2-byte-per-codepoint 中,UTF-16 会导致各种错误。
@o11c 没错,但除其他外,提供了所有拉丁变音符号,排序和比较没有问题,在其他国家显示这些字符也没有问题。使用 8 位字符本质上是一种要改掉的旧习惯。除非您有充分的技术理由。您能否提供一个与 Unicode 使用相关的错误示例?
@SQLPolice 尝试粘贴this gist 的内容,我会在另一条评论中。它适用于大多数基于 utf-8 的应用程序,但在许多基于 utf-16 的应用程序中失败(或显示错误)。【参考方案2】:
如 cmets 所述,您正在更新的列 (BurnhamGrade
) 可能不够大,无法容纳您插入其中的数据。
例如如果您的列定义是:BurnhamGrade VARCHAR(10)
,您将无法插入 'Grade II/III'
,因为它有 12 个字符长。
这会重现错误:
CREATE TABLE #data
(
MAXNVQ INT ,
BurnhamGrade VARCHAR(10)
)
INSERT INTO #data
( [MAXNVQ], BurnhamGrade )
VALUES ( 1, '' ),
( 3, '' ),
( 4, '' )
UPDATE #data
SET #data.BurnhamGrade = ( CASE WHEN MAXNVQ > 3 THEN 'Grade II/III'
WHEN MAXNVQ = 3 THEN 'Grade IV'
WHEN MAXNVQ < 3 THEN 'Grade IV'
END )
-- NOTE THE WHERE CLAUSE ISN'T REQUIRED UNLESS HANDLING NULLS
SELECT *
FROM #data
DROP TABLE #data
生产:
消息 8152,级别 16,状态 14,第 11 行 字符串或二进制数据将被截断。
将列规范修改为:BurnhamGrade VARCHAR(12)
允许它工作。
修改后会产生:
MAXNVQ BurnhamGrade
1 Grade IV
3 Grade IV
4 Grade II/III
因此,将列定义更改为更大的值应该可以解决问题。
最后一件事,您可以合并 2 个案例:
WHEN MAXNVQ = 3 THEN 'Grade IV'
WHEN MAXNVQ < 3 THEN 'Grade IV'
可以使用<= 3
,因为它们设置了相同的值,如下所示:
WHEN MAXNVQ <= 3 THEN 'Grade IV'
【讨论】:
【参考方案3】:看起来您尝试放入该字段的数据大于该字段允许的大小。您的 SQl 没有任何问题(除非 @sstan 在 cmets 中指出,不需要 where 子句)。
问题是如何处理它。你有两个选择,改变事物的决定是业务决策而不是编程决策。
您可以增加字段的大小以容纳所有可能的值。 或者 您可以更改可能的值,使其适合当前定义的字段大小。
我猜他们会更喜欢第一个解决方案,但这需要对您的应用程序以及使用该列的任何导入或导出或报告进行全面的回归测试。但是有时,模式是不可更改的,尤其是当您将数据放入为第三方应用程序设计的数据库时。在这种情况下,您别无选择,只能缩写该值以使其适合表格。
【讨论】:
以上是关于更新多个 WHERE SQL 不起作用 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章