我如何让select下面的字符串变成returns3? SELECT '1+2'
How do I select the following string so it returns 3? SELECT '1+2'
在 table 的第 "SumStrings" 列中,我有诸如“1+2”或“1+2-3”之类的字符串,如下所示:
SumStrings
1+2
1+2-3
换句话说:
DROP TABLE IF EXISTS #theSums;
CREATE TABLE #theSums (SumStrings VARCHAR(25))
INSERT INTO #theSums
values
('1+2'),
('1+2-3');
我如何 select 从这个 table 中得到这些总和的结果?也就是说,如果只有上述两个字符串在 table 中,那么 selection 的结果应该是 3 和 0
这个问题String Expression to be evaluated to number主要是针对函数的创建我想要一个简单的脚本,select来自table
您将必须查询字符串并在执行查询的程序中评估它们。这很重要,但有许多用 flex+bison(或其他工具)编写的语言示例,如果您真的、真的必须存储表达式而不是它们的值,它们将帮助您评估表达式。
这是使用 dynamic
sql
的一种方法
DECLARE @sql VARCHAR(8000)
SELECT @sql = Stuff((SELECT 'union all select ' + sumstrings
FROM #thesums
FOR xml path('')), 1, 9, '')
PRINT @sql
EXEC (@sql)
这里不容易...您可以使用动态创建的语句:
Prdp 的回答很好,只是针对 SQL-injection
的补充
您可以使用 XML 的隐式功能来计算 a - 这就是回退! - 文字 值。没有办法绕过动态 SQL,但这将有助于防止疯狂的值:
试试这个
SELECT CAST('' AS XML).value('1+2','int') AS Result;
这个例子有 CURSOR
,但同样可以用@Prdp 的方法来完成:
CREATE TABLE YourTable(ComputeString VARCHAR(100));
INSERT INTO YourTable VALUES('1+2'),('-2+3'),('3*(4+5)'),('12/4');
DECLARE @cs VARCHAR(100);
DECLARE c CURSOR FOR SELECT 'SELECT CAST('''' AS XML).value(''' + REPLACE(ComputeString,'/',' div ') + ''',''int'') AS Result;' FROM YourTable
OPEN c;
FETCH NEXT FROM c INTO @cs;
WHILE @@FETCH_STATUS=0
BEGIN
PRINT @cs
EXEC(@cs);
FETCH NEXT FROM c INTO @cs;
END
CLOSE c;
DEALLOCATE c;
GO
DROP TABLE YourTable;
备注
您必须将 /
作为除数运算符替换为 div
使用replace()
在+
和-
前加分隔符;拆分字符串,然后 sum()
:
在 SQL Server 2016+ 中你可以使用 string_split()
.
select
t.SumStrings
, Summed = sum(convert(int,s.value))
from #theSums t
cross apply string_split(replace(replace(SumStrings,'+','|+'),'-','|-'),'|') s
group by t.SumStrings
returns:
+------------+--------+
| SumStrings | Summed |
+------------+--------+
| 1+2 | 3 |
| 1+2-3 | 0 |
+------------+--------+
dbfiddle.uk 演示:http://dbfiddle.uk/?rdbms=sqlserver_2016&fiddle=abd084c8fe3758c29c26e29a1f9dfa36
在 SQL 2016 年之前的服务器中,使用 Jeff Moden 的 CSV Splitter table 值函数:
select
t.SumStrings
, Summed = sum(convert(int,s.Item))
from #theSums t
cross apply delimitedsplit8K(replace(replace(SumStrings,'+','|+'),'-','|-'),'|') s
group by t.SumStrings
rextester 演示:http://rextester.com/GTGT29482
returns:
+------------+--------+
| SumStrings | Summed |
+------------+--------+
| 1+2 | 3 |
| 1+2-3 | 0 |
+------------+--------+
拆分字符串的方法有很多种,这个基本前提适用于任何一种方法。
拆分字符串参考:
- Tally OH! An Improved SQL 8K “CSV Splitter” Function - Jeff Moden
- Splitting Strings : A Follow-Up - Aaron Bertrand
- Split strings the right way – or the next best way - Aaron Bertrand
string_split()
in SQL Server 2016 : Follow-Up #1 - Aaron Bertrand
- Ordinal workaround for **
string_split()**
- Solomon Rutzky
另一个动态sql
DECLARE @sql VARCHAR(8000) = ''
SELECT @sql = CONCAT( @sql , ' union all select ', ts.SumStrings)
FROM #theSums ts
SELECT @sql = STUFF(@sql, 1,10,'')
PRINT @sql
EXEC (@sql)
使用温度 table。从 sumString 中提取字符串公式并使用 select 执行它,然后将所需的值插入临时 table。逐行执行此操作。
设置 tables:
创建 TABLE sumString(
公式 varchar(20)
)
CREATE TABLE temp(
result varchar(20)
)
INSERT INTO sumString(formula)
VALUES
('1+3'),
('1+2-3')
解决方法:
DECLARE @expression varchar(20)
WHILE(EXISTS(SELECT 1 FROM sumString))
BEGIN
SELECT TOP(1) @expression = formula
FROM sumString
INSERT INTO temp
--the key is to execute with select as a string so the string formula will be evaluate
exec ('select '+ @exp)
DELETE TOP (1) FROM sumString
END
结果:
--check the result--
SELECT * FROM temp
result
4
0
在 table 的第 "SumStrings" 列中,我有诸如“1+2”或“1+2-3”之类的字符串,如下所示:
SumStrings
1+2
1+2-3
换句话说:
DROP TABLE IF EXISTS #theSums;
CREATE TABLE #theSums (SumStrings VARCHAR(25))
INSERT INTO #theSums
values
('1+2'),
('1+2-3');
我如何 select 从这个 table 中得到这些总和的结果?也就是说,如果只有上述两个字符串在 table 中,那么 selection 的结果应该是 3 和 0
这个问题String Expression to be evaluated to number主要是针对函数的创建我想要一个简单的脚本,select来自table
您将必须查询字符串并在执行查询的程序中评估它们。这很重要,但有许多用 flex+bison(或其他工具)编写的语言示例,如果您真的、真的必须存储表达式而不是它们的值,它们将帮助您评估表达式。
这是使用 dynamic
sql
DECLARE @sql VARCHAR(8000)
SELECT @sql = Stuff((SELECT 'union all select ' + sumstrings
FROM #thesums
FOR xml path('')), 1, 9, '')
PRINT @sql
EXEC (@sql)
这里不容易...您可以使用动态创建的语句:
Prdp 的回答很好,只是针对 SQL-injection
的补充您可以使用 XML 的隐式功能来计算 a - 这就是回退! - 文字 值。没有办法绕过动态 SQL,但这将有助于防止疯狂的值:
试试这个
SELECT CAST('' AS XML).value('1+2','int') AS Result;
这个例子有 CURSOR
,但同样可以用@Prdp 的方法来完成:
CREATE TABLE YourTable(ComputeString VARCHAR(100));
INSERT INTO YourTable VALUES('1+2'),('-2+3'),('3*(4+5)'),('12/4');
DECLARE @cs VARCHAR(100);
DECLARE c CURSOR FOR SELECT 'SELECT CAST('''' AS XML).value(''' + REPLACE(ComputeString,'/',' div ') + ''',''int'') AS Result;' FROM YourTable
OPEN c;
FETCH NEXT FROM c INTO @cs;
WHILE @@FETCH_STATUS=0
BEGIN
PRINT @cs
EXEC(@cs);
FETCH NEXT FROM c INTO @cs;
END
CLOSE c;
DEALLOCATE c;
GO
DROP TABLE YourTable;
备注
您必须将 /
作为除数运算符替换为 div
使用replace()
在+
和-
前加分隔符;拆分字符串,然后 sum()
:
在 SQL Server 2016+ 中你可以使用 string_split()
.
select
t.SumStrings
, Summed = sum(convert(int,s.value))
from #theSums t
cross apply string_split(replace(replace(SumStrings,'+','|+'),'-','|-'),'|') s
group by t.SumStrings
returns:
+------------+--------+
| SumStrings | Summed |
+------------+--------+
| 1+2 | 3 |
| 1+2-3 | 0 |
+------------+--------+
dbfiddle.uk 演示:http://dbfiddle.uk/?rdbms=sqlserver_2016&fiddle=abd084c8fe3758c29c26e29a1f9dfa36
在 SQL 2016 年之前的服务器中,使用 Jeff Moden 的 CSV Splitter table 值函数:
select
t.SumStrings
, Summed = sum(convert(int,s.Item))
from #theSums t
cross apply delimitedsplit8K(replace(replace(SumStrings,'+','|+'),'-','|-'),'|') s
group by t.SumStrings
rextester 演示:http://rextester.com/GTGT29482
returns:
+------------+--------+
| SumStrings | Summed |
+------------+--------+
| 1+2 | 3 |
| 1+2-3 | 0 |
+------------+--------+
拆分字符串的方法有很多种,这个基本前提适用于任何一种方法。
拆分字符串参考:
- Tally OH! An Improved SQL 8K “CSV Splitter” Function - Jeff Moden
- Splitting Strings : A Follow-Up - Aaron Bertrand
- Split strings the right way – or the next best way - Aaron Bertrand
string_split()
in SQL Server 2016 : Follow-Up #1 - Aaron Bertrand- Ordinal workaround for **
string_split()**
- Solomon Rutzky
另一个动态sql
DECLARE @sql VARCHAR(8000) = ''
SELECT @sql = CONCAT( @sql , ' union all select ', ts.SumStrings)
FROM #theSums ts
SELECT @sql = STUFF(@sql, 1,10,'')
PRINT @sql
EXEC (@sql)
使用温度 table。从 sumString 中提取字符串公式并使用 select 执行它,然后将所需的值插入临时 table。逐行执行此操作。
设置 tables: 创建 TABLE sumString( 公式 varchar(20) )
CREATE TABLE temp(
result varchar(20)
)
INSERT INTO sumString(formula)
VALUES
('1+3'),
('1+2-3')
解决方法:
DECLARE @expression varchar(20)
WHILE(EXISTS(SELECT 1 FROM sumString))
BEGIN
SELECT TOP(1) @expression = formula
FROM sumString
INSERT INTO temp
--the key is to execute with select as a string so the string formula will be evaluate
exec ('select '+ @exp)
DELETE TOP (1) FROM sumString
END
结果:
--check the result--
SELECT * FROM temp
result
4
0