我有这张桌子:
-----------------------------------------------
code intvalue checkrole result
-----------------------------------------------
A01 14 A02-A03 true
A02 24 A04 false
A03 10 A04 false
A04 12 A02/2 true
我想用查询或sp来填充列结果,基于列checkrole中描述的角色,类似Excel,任何想法?
我向大家道歉,我错误地解释了自己。例如:A01 14 A02-A03在这种情况下是真的,我想解释这个角色并获得24-10 = 14即真
更新2:大家好,感谢您的关注。 HABO,我正在朝着这个方向努力“将值替换为表达式(”24-10“)....”:
TBL
code intValue checkRule result
A01 14 select A02-A03 from Table_1 NULL
A02 24 select A04 from Table_1 NULL
A03 10 select A04 from Table_1 NULL
A04 12 select A02 / 2 from Table_1 NULL
SP
CREATE PROCEDURE [dbo]. [Test]
AS
BEGIN
DECLARE @code VARCHAR (50)
DECLARE @intvalue INT
DECLARE @checkrule VARCHAR (50)
DECLARE @cTbl AS CURSOR
SET @cTbl = CURSOR FOR SELECT code
, intValue
, checkRule
FROM [dbo]. [Table_1]
OPEN @cTbl FETCH NEXT FROM @cTbl INTO @code, @intvalue, @checkrule
WHILE @@ FETCH_STATUS = 0
BEGIN
declare @statement nvarchar (4000), @Result int, @Parm nvarchar (20)
SET @statement = 'select @Result = 11 + 7'
SET @Parm = '@Result int output'
EXEC sp_executesql @statement, @Parm, @ Result OUT
print @Result
FETCH NEXT FROM @cTbl INTO @code, @intvalue, @checkrule
END
CLOSE @cTbl
DEALLOCATE @cTbl
END
更新3:这就是我想要的。我不是专家,但我从错误中吸取教训,感谢那些教我新事物的人,感谢所有参与者,最重要的是感谢HOBO,晚上好
我可能会编写一个函数来创建checkRole的值列表(例如,它会从A02-A04给我列出'A02','A03','A04'然后我会用'contains'写一个更新语句声明
使用您显示的表可以使用下一个查询更新结果列的值
UPDATE TableName
SET result = CASE
WHEN checkrole = 'A02-A03' THEN "true"
WHEN checkrole = 'A04' THEN "false"
WHEN checkrole = 'A02/2' THEN "true"
ELSE "setDefaultValue"
END
WHERE code in (A01,A02,A03,A04);
在最后一行,您指定要更新的行的代码值。如果在列结果为空的情况下执行此查询,它将完成表并将结果生成与您在上面发布的数据相同的数据。
(查询在Mysql上运行良好)
执行摘要:这是一个糟糕的主意。慢慢退开,没有人受伤。
免责声明:在阅读超出此点之后,我不负责任何所需治疗的费用。
从您的更新2,您似乎可以控制CheckRule
的格式。要求用户界定Code
s要容易得多,例如:使用'«A04»'
而不是'A04'
,而不是尝试使用TSQL找到它们。当'A02'
是66
并获得CheckRule
时,你不需要担心用'A026 - BA02'
替换'666 - B66'
这样的问题。
接下来的事情简直太可怕了。它演示了一种蛮力方法,用表达式来定义具有分隔“变量”的表达式,例如: '«A04»'
,用其整数值替换每个“变量”的所有出现,评估结果表达式并检索结果。
它使用两个嵌套游标来蹒跚地穿过CheckRule
s和Code
s,而不是使用像游标一样令人反感的东西。从表达式解析“变量”并根据需要替换值而不是使用try-everything方法会更有效,但TSQL在实现parsers方面并不擅长。
为了额外的功劳,它还带来了拥抱SQL Injection的祝福。试试像CheckRule
这样的'A01; select 1 / 0;'
。不要试试像'-1; drop database LuckyGuess;'
这样的人。
-- Sample data.
declare @Samples as Table
( SampleId Int Identity, Code NVarChar(8), IntValue Int, CheckRule NVarChar(64), Result Bit );
insert into @Samples ( Code, IntValue, CheckRule ) values
( N'A01', 14, N'«A02» - «A03»' ),
( N'A02', 24, N'«A04»' ),
( N'A03', 10, N'«A04»' ),
( N'A04', 12, N'«A02» / 2' );
select * from @Samples;
-- Process the data.
declare Oy cursor forward_only fast_forward read_only
for select SampleId, Code, IntValue, CheckRule from @Samples;
declare @SampleId as Int, @Code as NVarChar(8), @IntValue as Int, @CheckRule as NVarChar(64);
declare Vey cursor forward_only fast_forward read_only
for select Code, IntValue from @Samples;
declare @VariableCode as NVarChar(8), @VariableIntValue as Int
-- For each row's CheckRule ...
open Oy;
fetch next from Oy into @SampleId, @Code, @IntValue, @CheckRule;
while @@Fetch_Status = 0
begin
-- Copy the CheckRule so that we can build the @Expression to evaluate.
declare @Expression as NVarChar(64) = @CheckRule;
-- For each Code that could appear in an @Expression ...
open Vey;
fetch next from Vey into @VariableCode, @VariableIntValue;
while @@Fetch_Status = 0
begin
-- Replace any occurrences of the Code in the @Expression with the corresponding integer value.
set @Expression = Replace( @Expression, N'«' + @VariableCode + N'»',
Cast( @VariableIntValue as NVarChar(10) ) );
fetch next from Vey into @VariableCode, @VariableIntValue;
end;
close Vey;
-- Make the @Expression an executable statement.
set @Expression = N'set @IntResult = ' + @Expression;
declare @Result as Int;
-- Evaluate the @Expression and get the @Result .
execute sp_executesql @Expression, N'@IntResult Int output', @IntResult = @Result output;
select @SampleId as SampleId, @Code as Code, @IntValue as IntValue, @CheckRule as CheckRule,
@Expression as Expression, @Result as Result;
fetch next from Oy into @SampleId, @Code, @IntValue, @CheckRule;
end;
close Oy;
deallocate Oy;
如果不清楚,不要。只是不要。