我的问题很简单。下面的查询返回错误:
Mensagem 537, Level 16, state 2, Line 1
传递给LEFT或SUBSTRING函数的长度参数无效…
代码:
Select
c.name "Nome Conta",
c.code "Código Conta",
sq1.[Nome Conta] Tipo
From
(chart_tag ct inner join chart c on ct.id_chart = c.id_chart) inner join
(Select
c1.name "Nome Conta",
LEFT(c1.code, (charindex('00', c1.code)-1)) "Código Conta"
from chart_tag ct1 inner join chart c1 on ct1.id_chart = c1.id_chart
where ct1.id_tag = 18159 and
c1.id_type_chart = 1942 and
c1.only_accrual = 1 and
c1.code not in ('99', '98')) sq1 on LEFT(c.code, 1) = sq1.[Código Conta]
Where
ct.id_tag = 18159 and
c.id_type_chart = 1942 and
c.only_accrual = 0
order by
c.code
第一个内部连接返回如下表:
顺便说一下,如果您只是想从数字中删除后面的0,您是否考虑过:
REPLACE((RTRIM(REPLACE(c1.code, '0', ' ')),' ', '0')
将所有0更改为空格,TRIM,并将剩余空格更改回…
会有更多的方法去剥猫的皮;
REVERSE(CAST(REVERSE(c1.code) as INT))
(但反过来通常被认为有点讨厌/慢)等。
那么,下面是调试方法:
- 当你不使用LEFT时,你不会得到错误
- 错误消息抱怨传递给LEFT的长度无效
- 问题出在LEFT函数
- 长度作为第二个参数传递
将c1.code
替换为某个值:
Select
LEFT('100', (charindex('00', '100')-1)) "Código Conta"
它工作,给你1
但. .如果在值中找不到要查找的字符串怎么办?
Select
LEFT('199', (charindex('00', '199')-1)) "Código Conta"
"无效长度……"误差
传递的长度是多少?只提取长度calc:
Select
charindex('00', '199')-1)
--LEFT('199', (charindex('00', '199')-1)) "Código Conta"
它给出-1,-1不是从左边删除的有效字符数…
那么,当你在干草堆里找不到针时,你想做什么呢?也许以没有子字符串的整个字符串为例?或者调整WHERE子句,只允许以00结尾的代码,这样seek就总是有效了?
你决定. .如果没有找到'00',这将给出全部内容:
Select
LEFT(
c1.code,
COALESCE(
NULLIF(
charindex('00', c1.code)-1,
-1
),
LEN(c1.Code)
)
) "Código Conta"
如果seek返回-1
,表示"未找到",则NULLIF
将-1转换为null
,COALESCE
将null
转换为LEN
,即LEFT
返回整个字符串
如果没有找到字符串,则返回空字符串;唯一的区别是在合并中使用了0——它要求LEFT给出最左边的0字符:
Select
LEFT(
c1.code,
COALESCE(
NULLIF(
charindex('00', c1.code)-1,
-1
),
0
)
) "Código Conta"
或者,如前所述,使用WHERE c1.code LIKE '%00%'
以确保您只查看真正包含00的代码
如果没有子字符串'00'
LEFT(c1.code, (charindex('00', c1.code)-1))
将给出错误,因为它返回0和-1无效
CASE WHEN charindex('00', c1.code) > 0
THEN LEFT(c1.code, (charindex('00', c1.code)-1))
ELSE c1.code
END
LEFT(c1.code+'00', (charindex('00', c1.code+'00')-1))
我相信第二个会更快,但它可能不是基于你的数据配置文件,所以如果性能真的很重要,测试两个。