Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.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 server SQL Server pad right脚本中无法解释的运算符优先级_Sql Server_Sql Server 2005_Tsql_Sql Server 2008 - Fatal编程技术网

Sql server SQL Server pad right脚本中无法解释的运算符优先级

Sql server SQL Server pad right脚本中无法解释的运算符优先级,sql-server,sql-server-2005,tsql,sql-server-2008,Sql Server,Sql Server 2005,Tsql,Sql Server 2008,作为生成零填充唯一标识符请求的一部分,我创建了一个我认为简单的语句 right('00000000' + convert(char(6),ID),6) 然而,这根本不是零填充字符。 进一步的调查显示,这一切并不像我预期的那样。 见: 其结果是: varcharPadRight charPadRight charPadRight20 vcharPadRight20 --------------- ------------ -------------- --------------- 000100

作为生成零填充唯一标识符请求的一部分,我创建了一个我认为简单的语句

right('00000000' + convert(char(6),ID),6)
然而,这根本不是零填充字符。 进一步的调查显示,这一切并不像我预期的那样。 见:

其结果是:

varcharPadRight charPadRight charPadRight20 vcharPadRight20
--------------- ------------ -------------- ---------------
000100          100          00000000100    00000000100
001000          1000         000000001000   000000001000
000001          1            000000001      000000001

其中,xtype 167是一个varchar

有没有人能解释导致这些(对我来说)意外结果的操作顺序


(这种行为在SQL Server 2005和2008中是一致的)

将int转换为char(6)是左对齐的,因此

   int -> char(6) -> '000' + char(6) -> right('000' + char(6))
    1  -> 1______ -> '0001_____'     -> '1_____'
    10 -> 10_____ -> '00010____'     -> '10____'
    etc
因此,代码中的rtrim将给出预期的结果 e、 g


简单的解释是char数据类型的右边有空格,使其成为变量的长度。因此,如果您有一个char(6)并将其设置为“3”,那么变量中的值实际上是3-space-space-space-space-space。这是一个3,后跟5个空格,使总长度=6个字符

在字符串左侧添加6个零时,SQL正在进行一些数据类型转换。硬编码字符串将导致varchar,因此“000000”的数据类型为varchar(6)。当您附加一个char和一个varchar时,结果是一个长度组合在一起的varchar

'000000' + Convert(Char(6), int)
VarChar(6) + Char(6)
varchar(12)
Char(6)部分仍将在数据右侧填充空格,因此当您使用最右边的6个字符时,您将获得空格

varchar的末尾没有空格,因此它的工作方式与您预期的完全相同

证明:

Declare @ID Int
Set @Id = 3

-- Data type after converting to char (results in char(6))
SELECT SQL_VARIANT_PROPERTY(Convert(Char(6), @id), 'BaseType') As DatType, 
       SQL_VARIANT_PROPERTY(Convert(Char(6), @id), 'MaxLength') As Length,
       Convert(Char(6), @id)

-- data type of hard coded string (Results in varchar(6))
SELECT SQL_VARIANT_PROPERTY('000000', 'BaseType') As DatType, 
       SQL_VARIANT_PROPERTY('000000', 'MaxLength') As Length,
       '000000'

-- data type of varchar concatenate char (Results in varchar(12))
SELECT SQL_VARIANT_PROPERTY('000000' + Convert(Char(6), @id), 'BaseType') As DataType,
       SQL_VARIANT_PROPERTY('000000' + Convert(Char(6), @id), 'MaxLength') As Length,
       '000000' + Convert(Char(6), @id)

-- data type of the result (results in varchar(6))
SELECT SQL_VARIANT_PROPERTY(Right('000000' + Convert(Char(6), @id), 6), 'BaseType') As DataType,
       SQL_VARIANT_PROPERTY(Right('000000' + Convert(Char(6), @id), 6), 'MaxLength') As Length,
       Right('000000' + Convert(Char(6), @id), 6)

只是使用
varchar()
而不是
char()
似乎是目前为止最明智的做法-它避免了在第一个位置添加填充字符。@Andriy M-可能,但我很困惑,因为OP似乎意识到
varchar()
是有效的(根据他们的第一个示例),所以我想我可能遗漏了什么。是的,我知道varchar正在修复它,只是想知道为什么。为SQL_VARIANT_属性干杯,这比tempdb hacking要好得多。
right('00000000' + rtrim(convert(char(6),ID)),6)
'000000' + Convert(Char(6), int)
VarChar(6) + Char(6)
varchar(12)
Declare @ID Int
Set @Id = 3

-- Data type after converting to char (results in char(6))
SELECT SQL_VARIANT_PROPERTY(Convert(Char(6), @id), 'BaseType') As DatType, 
       SQL_VARIANT_PROPERTY(Convert(Char(6), @id), 'MaxLength') As Length,
       Convert(Char(6), @id)

-- data type of hard coded string (Results in varchar(6))
SELECT SQL_VARIANT_PROPERTY('000000', 'BaseType') As DatType, 
       SQL_VARIANT_PROPERTY('000000', 'MaxLength') As Length,
       '000000'

-- data type of varchar concatenate char (Results in varchar(12))
SELECT SQL_VARIANT_PROPERTY('000000' + Convert(Char(6), @id), 'BaseType') As DataType,
       SQL_VARIANT_PROPERTY('000000' + Convert(Char(6), @id), 'MaxLength') As Length,
       '000000' + Convert(Char(6), @id)

-- data type of the result (results in varchar(6))
SELECT SQL_VARIANT_PROPERTY(Right('000000' + Convert(Char(6), @id), 6), 'BaseType') As DataType,
       SQL_VARIANT_PROPERTY(Right('000000' + Convert(Char(6), @id), 6), 'MaxLength') As Length,
       Right('000000' + Convert(Char(6), @id), 6)