UPDATE多个WHERE SQL无法正常工作

时间:2015-06-30 14:54:53

标签: sql sql-server

我正在尝试运行查询来更新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执行错误:

  

字符串或二进制数据将被语句截断   终止。

就像我在SQL中的错误一样

3 个答案:

答案 0 :(得分:4)

也许这应该是一个评论,但评论似乎是关于其他主题。您的查询(或等效的)是:

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),
    . . .
);

或者,如果此映射始终为true,则将值存储在引用表中并使用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)

使用这种方法,您不必担心保持最新值。每当您查询表并使用该列时,它都是正确的。

答案 1 :(得分:3)

正如评论中所述,您要更新的列(BurnhamGrade)可能不足以保存您要插入的数据。

E.g。如果您的列定义为: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

<强>产地:

  

Msg 8152,Level 16,State 14,Line 11   字符串或二进制数据将被截断。

将列规范修改为:BurnhamGrade VARCHAR(12)使其可以正常工作。

更改后,它会生成:

MAXNVQ  BurnhamGrade
1       Grade IV
3       Grade IV
4       Grade II/III

因此,将列定义更改为更大的值应该可以解决问题。

最后一件事,你可以合并你的两个案例:

WHEN MAXNVQ = 3 THEN 'Grade IV'
WHEN MAXNVQ < 3 THEN 'Grade IV'

可以使用<= 3,因为它们设置相同的值,如下所示:

WHEN MAXNVQ <= 3 THEN 'Grade IV'

答案 2 :(得分:0)

您尝试在字段中放置的数据看起来好像是字段允许的大小。你的SQl没有任何问题(除非@sstan在评论中指出,不需要clasue)。

问题是如何处理它。你有两个选择,改变事物的决定是一个商业决策而不是一个编程决策。

您可以增加字段的大小以容纳所有可能的值。  要么 您可以更改可能的值,使其符合当前定义的字段大小。

我猜他们会更喜欢第一种解决方案,但这需要对您的应用程序以及使用该列的任何导入或导出或报告进行完全回归测试。但有时,架构不可更改,尤其是在将数据放入为第三方应用程序设计的数据库中时。在这种情况下,您别无选择,只能缩写该值以使其适合表格。