Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL-“;递增“;字符值导致排序错误_Sql_Sql Server_Sql Server 2008_Collation - Fatal编程技术网

SQL-“;递增“;字符值导致排序错误

SQL-“;递增“;字符值导致排序错误,sql,sql-server,sql-server-2008,collation,Sql,Sql Server,Sql Server 2008,Collation,我正在处理一个表,其中一组任意设置存储为VARCHAR(255)值。我的任务是处理一个需要递增并返回给调用方的序列号。(再次注意,序列“number”存储为VARCHAR,这是我无法控制的) 因为它是一个序列号,我真的不想在单独的步骤中进行选择和更新。当我过去用实际的数字字段处理这类事情时,我的方法是 UPDATE TABLE SET @SEQ_NUM = VALUE = VALUE + 1 这会增加值,并在一个foop中提供更新的值。我想在这种情况下,我会尝试同样的基本方法: DECLARE

我正在处理一个表,其中一组任意设置存储为
VARCHAR(255)
值。我的任务是处理一个需要递增并返回给调用方的序列号。(再次注意,序列“number”存储为
VARCHAR
,这是我无法控制的)

因为它是一个序列号,我真的不想在单独的步骤中进行选择和更新。当我过去用实际的数字字段处理这类事情时,我的方法是

UPDATE TABLE SET @SEQ_NUM = VALUE = VALUE + 1
这会增加值,并在一个foop中提供更新的值。我想在这种情况下,我会尝试同样的基本方法:

DECLARE @SEQ_NUM VARCHAR(255)

UPDATE SOME_TABLE
    SET @SEQ_NUM = VALUE = CAST((CAST(VALUE AS INT) + 1) AS VARCHAR) 
WHERE NAME = 'SOME_NAME'
只要我不尝试将结果分配给变量,实际的更新就可以正常工作;一旦我这样做,我就会收到以下错误:

Msg 549,16级,状态1,第4行排序规则 接收变量的“SQL\u Latin1\u General\u CP1\u CI\u AS”不等于 “VALUE”列的排序规则“Latin1\u General\u BIN”

我明白这意味着什么,但我不明白为什么会发生这种情况,或者说,如何解决这个问题


除了修复特定错误之外,我还欢迎提供增加字符序列“编号”的替代方法的建议。

手动维护序列号决不是我想使用的解决方案,但我可以理解这可能存在一些限制

如果你把它分解成两个步骤,那么你就可以解决这个问题。注意,我已将此示例代码的
WHERE
子句替换为:

CREATE TABLE #SOME_TABLE ( [VALUE] VARCHAR(255) )

INSERT  INTO #SOME_TABLE
        ( VALUE )
VALUES  ( '12345' )

DECLARE @SEQ_NUM VARCHAR(255) 

UPDATE  #SOME_TABLE
SET     [VALUE] = CAST(( CAST([VALUE] AS INT) + 1 ) AS VARCHAR(255))
WHERE   1 = 1

SELECT  *
FROM    #SOME_TABLE

SELECT  @SEQ_NUM = [VALUE]
FROM    #SOME_TABLE
WHERE   1 = 1

SELECT  @SEQ_NUM

DROP TABLE #SOME_TABLE

从其中一条评论中,听起来你可能已经意识到了这一点,但我建议如下:

UPDATE TABLE
SET VALUE = CAST((CAST(VALUE AS INT) + 1) AS VARCHAR) 
OUTPUT inserted.VALUE
WHERE NAME = 'SOME_NAME'
这将像
SELECT
语句一样输出新值。如果希望在SQL中执行此操作,还可以将
inserted.VALUE
强制转换为
int

如果要将值放入
@SEQ_NUM
而不是从语句/存储过程输出值,则不能使用标量变量,但可以将其泵入表变量,如下所示:

DECLARE @SEQ_NUM AS TABLE ( VALUE VARCHAR(255) );

UPDATE TABLE
SET VALUE = CAST((CAST(VALUE AS INT) + 1) AS VARCHAR) 
OUTPUT inserted.VALUE INTO @SEQ_NUM ( VALUE )
WHERE NAME = 'SOME_NAME'

SELECT VALUE FROM @SEQ_NUM

您可以继续在OP中使用古怪的update,但必须将
update
语句中的三重赋值
@Variable=Column=Expression
拆分为两个简单赋值
@Variable=Expression
Column=@Variable
,如下所示

CREATE TABLE #SOME_TABLE (
    NAME VARCHAR(255)
    , VALUE VARCHAR(255) COLLATE Latin1_General_BIN
    )
INSERT #SOME_TABLE SELECT 'SOME_NAME', '42'

DECLARE @SEQ_NUM VARCHAR(255)

/*
-- this quirky update fails on COLLATION mismatch or data-type mismatch
UPDATE #SOME_TABLE
    SET @SEQ_NUM = VALUE = CAST((CAST(VALUE AS INT) + 1) AS VARCHAR) 
WHERE NAME = 'SOME_NAME'
*/

-- this quirky update works in all cases
UPDATE #SOME_TABLE
    SET @SEQ_NUM = CAST((CAST(VALUE AS INT) + 1) AS VARCHAR) 
        , VALUE = @SEQ_NUM
WHERE NAME = 'SOME_NAME'

SELECT *, @SEQ_NUM FROM #SOME_TABLE

这种简单的重写可以防止数据库引擎抱怨
@Variable
Column
之间的数据类型差异(例如
VARCHAR
vs
NVARCHAR
),这似乎是一种更为“便携”的方式来进行奇怪的更新(如果有这种情况的话)

为什么还要维护自己的序列号?它充满了并发性等问题。因为设计这个的人没有想到你会在这里打一场败仗。你可以使用
COLLATE
关键字来解决这个问题。@SeanLange,相信我,我知道。幸运的是,这个特定的用例不会经常使用,但它仍然是一个巨大的PITA。@GordonLinoff——具体是如何使用的?我尝试对计算出的值强制进行排序,如:“SET SEQ_NUM=value=CAST((CAST(value AS INT)+1)AS VARCHAR)COLLATE SQL\u Latin1\u General\u CP1\u CI\u AS”,但收到了相同的错误。我不知道如何在变量本身上设置COLLATE值(并不是说我不知道某件事意味着什么)。我还没有试过这个替代方法,但我在考虑一种类似于您所概述的方法,除了在查询中使用表var和OUTPUT子句之外。这正是我现在正在做的。我在一个存储过程中执行此更新,需要返回值;除了将输出插入到表var中并选择返回的值之外,是否有一种简化的替代方法?如果输出没有插入到表变量中,我就不太熟悉它的操作。因此,这两个代码块将做完全相同的事情——从存储过程中输出新值。如果不需要在存储过程中操作值,则使用第一个块,当读取代码中返回的数据时(例如,通过
ExecuteScalar
),它将具有新值。