我有以下用于转换数据的sql查询,但是可以在某些变量中保存int的值以避免多次转换吗?
update prospekts set sni_kod = case
when
cast(sni_kod as int) >= 1000 and cast(sni_kod as int) <= 1499
or cast(sni_kod as int) >= 1600 and cast(sni_kod as int) <= 2439
then '1'
when
cast(sni_kod as int) >= 7000 and cast(sni_kod as int) <= 7499
then 'W'
else
sni_kod
end
脚本中有更多的案例,只显示第一个案例。我不能使用除简单文本脚本之外的任何东西。
更新 使用SQL Server 2000
由于
的Anders
答案 0 :(得分:3)
好的......这是我对你的代码的重写......
UPDATE prospekts SET sni_kod =
CASE
WHEN ISNUMERIC(@sni_kod)=1 THEN
CASE
WHEN cast(@sni_kod as int) BETWEEN 1000 AND 1499 OR cast(@sni_kod as int) BETWEEN 1600 AND 2439 THEN '1'
WHEN cast(@sni_kod as int) BETWEEN 7000 AND 7499 THEN 'W'
ELSE @sni_kod
END
ELSE @sni_kod
END
这样,如果它是一个数值,它只会尝试进行CAST,所以你不会像其他人在评论中提到的那样获得强制转换异常。
既然你说有更多的陈述涉及,我猜你有更多的数字范围得到不同的价值......如果是这样,你可能能够使用第二个表(可以是一个临时的,如果,如你的问题所说,你只限于SQL代码)加入哪个有最小值,最大值,以及你想要显示的内容。当你需要评估非数字值时会变得更加棘手,但这并非不可能。
虽然没有看到完整的陈述,但这是我能提供的最佳陈述。
答案 1 :(得分:2)
这只是一个一次性的脚本吗?如果是这样,你只是想节省打字,那么写为:
update prospekts set sni_kod = case
when
xxx >= 1000 and xxx <= 1499
or xxx >= 1600 and xxx <= 2439
then '1'
when
xxx >= 7000 and xxx <= 7499
then 'W'
else
sni_kod
end
...然后进行全局搜索并替换为文本编辑器。
或许您可能会担心每次投射几次的性能?但同样,如果这个剧本是一次性的,那真的很重要吗?
答案 2 :(得分:2)
在你的问题中,你提到你想“避免多次投射”。如果您担心性能问题,那就不要了。 SQL不会多次转换该字段(即使您在脚本中多次使用它)。
示例:
SELECT CONVERT(INT, '123'), CONVERT(INT, '123')
T-SQL只运行一次该方法(没有性能损失)。
话虽如此,那么唯一可能有的另一个问题就是输入一堆......如果是这样的话,那么Tony Andrews提到的“xxx / find and replace”评论已经足够了。
答案 3 :(得分:1)
您可以使用子查询或CTE:
With xxx AS (
i_sni_kod = cast(sni_kod as int)
...)
UPDATE prospekts set sni_kod = case
when i_sni_kod >= 100 ...
答案 4 :(得分:0)
这是否适用于您的DBMS?
update (select prospekts.*, cast(sni_kod as int) sni_kod_int from prospekts)
set sni_kod = case
when
sni_kod_int >= 1000 and sni_kod_int <= 1499
or sni_kod_int >= 1600 and sni_kod_int <= 2439
then 1
else
sni_kod
end
答案 5 :(得分:0)
这似乎是您的模型的问题,而不是您的查询。为什么该列不仅仅是一个int?
这似乎是一个shoe or glass bottle问题。您看到的多重投射问题仅仅是早期不良做法的结果。解决这些问题,你的问题就会消失。
答案 6 :(得分:0)
这样的事可能会奏效:
update prospekts set sni_kod = 1
from prospekts
join (select prospekts.primarykey, cast(prospekts.sni_kod as int) as sni_kod_int from prospekts) p2 on prospekts.primarykey = p2.primarykey
WHERE (p2.sni_kod_int >=1000 and p2.sni_kod_int <= 1499)
or (p2.sni_kod_int >=1600 and p2.sni_kod_int <= 2439)
答案 7 :(得分:0)
您显示的UPDATE语句;我假设它只会运行一次?如果它再次运行,则当它找到在上一次运行中添加的“W”时,转换为int将失败。 这里最好的选择是更改sni_kod列的数据类型。也许你可以解释这个专栏的内容,为什么需要同时保存int和varchar数据? 最后,SQL服务器几乎肯定只进行一次转换。它非常适合在查询中查找重复的表达式和子查询,并且只运行一次。如果您不确定,请查看执行计划。
答案 8 :(得分:0)
我看到有人发布了一个在from子句中加入子查询的解决方案。这是一个解决方案-just- from子句中的子查询。
DECLARE @MyTable TABLE
(
theKey int identity(1,1) PRIMARY KEY,
theValue varchar(30)
)
------
INSERT INTO @MyTable SELECT '1'
INSERT INTO @MyTable SELECT '2'
INSERT INTO @MyTable SELECT '3'
------
UPDATE sub
SET theValue =
CASE
WHEN convertedvalue % 2 = 0 THEN 'even'
ELSE theValue
END
FROM
(
SELECT
CASE
WHEN Isnumeric(theValue) = 1
THEN convert(int, theValue)
ELSE null
END as convertedValue, *
FROM @MyTable mt
) as sub
------
SELECT *
FROM @MyTable