• 全部
  • 基础类
  • 应用实例
  • 新技术前沿

substring中的汉字问题

mathematician 2012-09-07 02:29:12
银行系统发给我的定长字符串:5位帐号+10位姓名+5位金额+10位备注信息,我收到此字符串后保存至sql server表中,用substring拆分它,希望得到帐号、姓名、金额和备注信息。

问题在于:银行系统定义1个汉字占2个字节,姓名、备注信息中包含了汉字,原本应该
姓名 = 张三+8个空格
根据银行的定义,实际就变成了:
姓名 = 张三+6个空格

例如:
bankstring = "11111张三 22.22客户转账"

这样我用substring(bankstring,6,10)就取不到正确的姓名,同理也取不到正确的备注信息,再者,有的姓名还可能是三个字的,请问我该怎么写呢?感谢!
...全文
357 点赞 收藏 21
写回复
21 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
Limpire 2012-09-07
[Quote=引用 16 楼 的回复:]

感谢各位的回复,实际上比这个复杂,判断数字或者汉字的方法恐怕不行的
下面是实际的两条记录:

SQL code
00183000000000038 201209071122106223190210589245 王二 1177527.27 ……
[/Quote]

转换为binary按字节截取,仍以1楼数据为例:
declare @str varchar(1000) = '11111张三      22.22客户转账'
declare @bin varbinary(1000) = convert(varbinary(1000), @str)
select convert(varchar, substring(@bin,1,5)) -- 5位帐号
select convert(varchar, substring(@bin,6,10)) -- 10位姓名
select convert(varchar, substring(@bin,16,5)) -- 5位金额
select convert(varchar, substring(@bin,21,10))-- 10位备注信息

实际数据同理
回复
DBA_磊仔 2012-09-07
数据从这两串数提取?
你先手动拆开一个示例,我们试试能不能用sql实现
你的两行数我都没能和你的字段对应上,你的数据格式还算严格,应该可以提取
回复
汤姆克鲁斯 2012-09-07
[Quote=引用 18 楼 的回复:]

我做过银行报文。
是在外部程序端实现解析。不要在数据库层实现。
[/Quote]
同意,如果特别复杂的 就用程序去解析 正则什么的 比数据库来的容易。
回复
yy1987316 2012-09-07
我做过银行报文。
是在外部程序端实现解析。不要在数据库层实现。
回复
汤姆克鲁斯 2012-09-07
[Quote=引用 16 楼 的回复:]

感谢各位的回复,实际上比这个复杂,判断数字或者汉字的方法恐怕不行的
下面是实际的两条记录:

SQL code
00183000000000038 201209071122106223190210589245 王二 1177527.27 ……
[/Quote]
我擦 他就这么给你一串啊,这也太不负责人了吧


下面的算一个字符串???


00183S69900000049 201209071347406223190210589285 Ecode =S099 | Emsg = 卡号:6223190210589247,卡档记录不存在 01xnhc
回复
mathematician 2012-09-07
感谢各位的回复,实际上比这个复杂,判断数字或者汉字的方法恐怕不行的
下面是实际的两条记录:

00183000000000038        201209071122106223190210589245         王二                                    1177527.27                                                               01xnhc



00183S69900000049        201209071347406223190210589285                                                              Ecode =S099 | Emsg = 卡号:6223190210589247,卡档记录不存在   01xnhc


字段名称 数据类型 说明
长度 Char(5) 长度(包含自身)00183
响应码 Char(4)
流水号sn Char(16)
交易完成时间 Char(14) 格式yyyymmddhhmmss
客户账号 Char(25)
客户姓名 Char(40)
账户余额 Char(13)
错误信息 Char(60)
通道号 Char(2)
交易代码 Char(4) 常量(xnhc)

如何取出各个数据项?用判断汉字开始位置的方法恐怕不行
回复
汤姆克鲁斯 2012-09-07
如果金额不固定


DECLARE @s VARCHAR(30)
SET @s='11111张三 22.22客户转账'
--1
SELECT SUBSTRING(SUBSTRING(@s,PATINDEX('%[^0-9][0-9]%',@s),15),0,PATINDEX('%[^0-9][吖-做]%',SUBSTRING(@s,PATINDEX('%[^0-9][0-9]%',@s),15)))
--3 备注
SELECT REVERSE(SUBSTRING(REVERSE(@s),0,PATINDEX('%[0-9]%',REVERSE(@s))))
回复
mathematician 2012-09-07
汤姆克鲁斯:金额是5位的,小数点算一位,如:12.10
如果为:1.00 ,后面就会接一个空格。

举的这个例子是我简化了的,实际项目中的金额为16位,银行整个字符串长度是231位,包含了大量的信息
回复
DECLARE @s VARCHAR(30)
SET @s='11111张三 22.22客户转账'

SELECT SUBSTRING(@s,6,PATINDEX('%[^0-9][0-9]%',@s)-5) --姓名


SELECT SUBSTRING(@s,PATINDEX('%[^0-9][0-9]%',@s),6) --金额


SELECT SUBSTRING(@s,PATINDEX('%[^0-9][0-9]%',@s)+6,10) --备注
回复
binsir543 2012-09-07
不错不错
回复
汤姆克鲁斯 2012-09-07
[Quote=引用 9 楼 的回复:]

引用 5 楼 的回复:

DECLARE @s VARCHAR(30)
SET @s='11111张三 22.22客户转账'
SELECT PATINDEX('%[^0-9][0-9]%',@s)
SELECT SUBSTRING(@s,6,PATINDEX('%[^0-9][0-9]%',@s)-5)

因为你的后面是金额2左边要么是姓名 要么是空格
根据这个特性找……
[/Quote]

金额是不是也不固定长度?
回复
fmilan 2012-09-07
可以先取ascii码判断是否汉字
回复
mathematician 2012-09-07
[Quote=引用 5 楼 的回复:]

DECLARE @s VARCHAR(30)
SET @s='11111张三 22.22客户转账'
SELECT PATINDEX('%[^0-9][0-9]%',@s)
SELECT SUBSTRING(@s,6,PATINDEX('%[^0-9][0-9]%',@s)-5)

因为你的后面是金额2左边要么是姓名 要么是空格
根据这个特性找到这个位置,然后截取 你测试一下……
[/Quote]

这个方法可以取出姓名,但是金额呢?
回复
mathematician 2012-09-07
[Quote=引用 3 楼 的回复:]

楼主,我想请问下,这个应该有合并规律的吧,不应该是用字节去限制每个类别信息的吧,它是否有特殊符号来大类小类的区分!
请给一个演示数据!
[/Quote]

定长字符串,我通过“SOCKET短连接”接收到银行系统发给我的30位字符串,一次连接接收一条数据,每次的数据的长度必定是30位的(汉字占2位):

5位帐号+10位姓名+5位金额+10位备注信息

根据各个字段的长度截取对应的信息,别无他法。

不需要合并,也没有什么大类、小类之说。
回复
汤姆克鲁斯 2012-09-07
[Quote=引用 6 楼 的回复:]

引用 2 楼 的回复:

这个简单啊

先replace一下 把一个空格替换成两个 然后在截取


英文、数字占一位,汉字占2位,如果全部替换成双倍的空格,数据就乱了。
例如:如果帐号,金额字段包含了空格,如5位的金额=1.20+1个空格,替换了就找不到substring的位置了
[/Quote]
看5楼
回复
mathematician 2012-09-07
[Quote=引用 2 楼 的回复:]

这个简单啊

先replace一下 把一个空格替换成两个 然后在截取
[/Quote]

英文、数字占一位,汉字占2位,如果全部替换成双倍的空格,数据就乱了。
例如:如果帐号,金额字段包含了空格,如5位的金额=1.20+1个空格,替换了就找不到substring的位置了
回复
汤姆克鲁斯 2012-09-07
DECLARE @s VARCHAR(30)
SET @s='11111张三 22.22客户转账'
SELECT PATINDEX('%[^0-9][0-9]%',@s)
SELECT SUBSTRING(@s,6,PATINDEX('%[^0-9][0-9]%',@s)-5)

因为你的后面是金额2左边要么是姓名 要么是空格
根据这个特性找到这个位置,然后截取 你测试一下
回复
汤姆克鲁斯 2012-09-07
[Quote=引用 2 楼 的回复:]

这个简单啊

先replace一下 把一个空格替换成两个 然后在截取
[/Quote]
不要意思,激动了一下
回复
xuzhe527843733 2012-09-07
楼主,我想请问下,这个应该有合并规律的吧,不应该是用字节去限制每个类别信息的吧,它是否有特殊符号来大类小类的区分!
请给一个演示数据!
回复
汤姆克鲁斯 2012-09-07
这个简单啊

先replace一下 把一个空格替换成两个 然后在截取

回复
发帖
MS-SQL Server
创建于2007-09-28

3.3w+

社区成员

MS-SQL Server相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2012-09-07 02:29
社区公告
暂无公告