Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.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 2008和早期版本中读取带有奇怪字符的字符串时出现问题_Sql Server_Sql Server 2008_Tsql_Unicode - Fatal编程技术网

Sql server 在SQL Server 2008和早期版本中读取带有奇怪字符的字符串时出现问题

Sql server 在SQL Server 2008和早期版本中读取带有奇怪字符的字符串时出现问题,sql-server,sql-server-2008,tsql,unicode,Sql Server,Sql Server 2008,Tsql,Unicode,我今天的问题是:我们将一些信息从文本文件加载到SQLServer表中。问题是,对于一个字段,我意识到字符串值有点奇怪 使用SQL Server client 2008或更早版本查询表时,得到以下结果集: 即使我尝试运行下面这样的查询,结果集也是空的: select REPLACE(LTRIM(RTRIM(cust_po)), ' ', ' ') from dbo.test_char where cust_po like '%076929%' 奇怪的是:对于SQL Server 2016,

我今天的问题是:我们将一些信息从文本文件加载到SQLServer表中。问题是,对于一个字段,我意识到字符串值有点奇怪

使用SQL Server client 2008或更早版本查询表时,得到以下结果集:

即使我尝试运行下面这样的查询,结果集也是空的:

select REPLACE(LTRIM(RTRIM(cust_po)), '  ', ' ') 
from dbo.test_char
where cust_po like '%076929%'
奇怪的是:对于SQL Server 2016,只打开表看起来很正常,尽管查询也不会返回任何结果:

现在,根据@SolomonRutzky的两条指令,我执行了下面的查询,以获得varbinary中的结果

新结果为:0x30003700360390032003900BC05BC05BC05BC05BC05BC05BC05BC05BC05BC05BC05BC05BC05BC05

如果没有奇怪的字符或空间或其他地方,怎么能把它作为varchar呢?

怎么回事? 现在数据的
VARBINARY
表示已经发布,问题就清楚多了

如我们所见,带有“奇数”字符的两行是:

0x300037003600390032003900BC05BC05BC05BC05BC05BC05BC05BC05BC05
此列为
NVARCHAR
,这意味着编码为UTF-16 Little-Endian。UTF-16意味着我们查看每个2字节块(字符将是这些2字节块的1或2组),而小尾端意味着每个2字节块中的字节顺序相反。也就是说,第一个字符是
3000
(2个字节),它等于代码点U+0030,即数字
0
。下一个字符是
3700
,它是代码点U+0037,它是编号
7
。依此类推,直到值中的最后一个
9

然后我们得到九组
BC05
,这是代码点U+05BC,这是。这就是它变得有趣的地方,因为这里有三件不同的事情:

  • 显示的是所用字体的函数。并不是所有字体都能正确处理所有字符,甚至不是所有字符都有映射。这就是为什么在结果网格的左侧看到一系列圆圈,在行编辑器的最左侧看到一个点(很难看到,特别是当您不知道如何查找它,但仔细查看行编辑器图像时,顶部两行在
    0
    的左侧都有一个小点)
  • 希伯来语是一种从右向左的语言,这解释了为什么结果网格中的圆圈位于左侧,即使数据中的字符位于数字之后
  • 这个特殊字符是一个组合字符,这意味着它应该附加到它前面的字符。由于不同的字体显示不同的字符,因此您可以看到结果网格和行编辑器之间的差异。结果网格字体似乎无法正确处理此字符,而行编辑器却可以。但是,在正确处理它时,我们看到这个组合字符不允许显示倍数,所以我们看到的是最左边的一个点,而不是9个点(但所有9个都在那里,只有一个在另一个上面)
  • 要查看此操作,请执行以下查询:

    选择N'4 11'+复制(NCHAR(0x05BC),10)+N'88 f';
    
    返回:

    4 11、88 f 请注意第二个
    1
    左侧的单点。即使字符串中有10个单点(由于
    REPLICATE
    ),也只有一个单点。这就是我的浏览器显示的内容,如下图所示:

    但我在我的结果表格中看到了以下内容:

    注意点是如何位于第一个而不是第二个
    1
    的左侧,以及
    11
    88
    f
    之间的位置

    如果我将结果网格复制并粘贴到查询编辑器中,我会看到:

    请注意,有几个红点

    为什么
    像“%076929%”这样的客户订单不返回任何行?
    

    这是因为字符串比较做了它应该做的事情和应用语言规则。不管字节的顺序是什么,重要的是从人的角度来看它是如何呈现字符串的。而且由于这个特殊字符是一个组合字符,它不在前面的字符后面,它是PAR。也就是说,您的

    076929
    值中的第二个
    9
    不再是
    9
    ,而是
    9
    +Dagesh

    选择1,其中
    N'123'+复制(NCHAR(0x05BC),5)类似于N'%123'+复制(NCHAR(0x05BC),4)+N'%;
    --没有返回行
    选择2个位置
    N'123'+复制(NCHAR(0x05BC),5)类似于N'%123'+复制(NCHAR(0x05BC),5)+N'%;
    -- 2
    选择3,其中N'9'+NCHAR(0x05BC)=N'9'
    --没有返回行
    
    你如何摆脱那些角色? 假设此U+05BC字符是数据中唯一的问题,您可以执行简单的替换。您已经尝试过此操作,但是
    replace
    找不到匹配项。发生这种情况时,您需要使用二进制排序规则,如下所示:

    选择替换(N'4 11'+复制(NCHAR(0x05BC),5)+N'88 f',
    NCHAR(0x05BC)校对拉丁文1\u General\u 100\u BIN2,
    N‘~’);
    --4 11 ~~~~~88华氏度
    
    首先-当@solomon Rutzky查看您的代码时,您会得到很好的帮助;)

    我目前还没有NVarchar版本,但是,如果您只希望列中的数值,那么可以使用。解决方案看起来是这样的

    -- sample data with a couple characters to screw you up. 
    DECLARE @table TABLE (somestring nvarchar(100));
    INSERT @table
    SELECT CONCAT(NCHAR(365), '123') UNION ALL
    SELECT CONCAT(CHAR(0), '789');
    
    -- solution
    SELECT *
    FROM @table t
    CROSS APPLY dbo.DigitsOnlyEE(t.somestring);
    
    结果:

    somestring   DigitsOnly
    ------------ ------------
    ŭ123         123
     789         789
    

    这有用吗?为什么显示SSMS 2008的查询结果而显示SSMS 2016的表编辑器?看到与第一张图像相同的输出将很有帮助,但对于SSMS 2016(因为您在那里做了区分)。但是,不要执行最初使用的查询,而是执行以下命令,然后发布结果的图像:
    SELECT cust\u po,CONVERT(VARB