我有ms访问数据库,我想转换Sql Server。
我的txttotal列有一个($family = "mom dad sister brother";
$f = explode(' ', $family);
$nice = ' is nice';
echo $nice_family = implode($nice.', ' ,$f).$nice;
)值
我的Sum函数很好地工作了我的旧访问数据库这个查询:
15,50 1,25 10,00
访问检索真值(26,75)
但我尝试使用此查询的SQL Server:
dtfr = DateTimePicker1.Value
dtto = DateTimePicker2.Value
sqlcmd = "SELECT SUM(txttotal) as Total from table WHERE odate >= CDate('" + dtfr + "') AND odate <= CDate('" + dtto + "')"
?=我试过float,int,double
SqlException&#34; 将数据类型varchar转换为float时出错&#34;
编辑:我的txttotal列是varchar
答案 0 :(得分:2)
请勿使用字符串连接将数据输入SQL查询!
这会导致Sql Injection攻击。关于你需要什么值的问题是完全清楚的,但是猜测样本是用逗号分隔的4条记录,并且你只想要每条记录中空格之前的部分,而是这样做:
Dim sql As String = _
"SELECT SUM(CAST(LEFT(txttotal, " & _
" CASE WHEN charindex(' ', txttotal) = 0 THEN LEN(txttotal) ELSE charindex(' ', txttotal) - 1 END " & _
" ) As Integer)) as Total" & _
" FROM table WHERE odate >= @DateFrom AND odate <= @DateTo"
Using cn As New SqlConnection("connection string here"), _
cmd As New SqlCommand(sql, cn)
cmd.Parameters.Add("@DateFrom", SqlDbType.DateTime).Value = DateTimePicker1.Value
cmd.Parameters.Add("@DateTo", SqlDbType.DateTime).Value = DateTimePicker2.Value
cn.Open()
Dim rdr As SqlDataReader = cmd.ExecuteReader()
'Do something with the reader here
End Using
或DataSet / DataTable解决方案:
Dim result As New DataTable
Dim sql As String = _
"SELECT SUM(CAST(LEFT(txttotal, " & _
" CASE WHEN charindex(' ', txttotal) = 0 THEN LEN(txttotal) ELSE charindex(' ', txttotal) - 1 END " & _
" ) As Integer)) as Total" & _
" FROM table WHERE odate >= @DateFrom AND odate <= @DateTo"
Using cn As New SqlConnection("connection string here"), _
cmd As New SqlCommand(sql, cn)
cmd.Parameters.Add("@DateFrom", SqlDbType.DateTime).Value = DateTimePicker1.Value
cmd.Parameters.Add("@DateTo", SqlDbType.DateTime).Value = DateTimePicker2.Value
cn.Open()
result.Load(cmd.ExecuteReader())
End Using
根据一些评论,它开始听起来像空格只是一个缺少的小数分隔符。如果是这种情况,SUM()
表达式非常简单:
SUM(CAST(REPLACE(txttotal, ' ', '.') As numeric(5,2)))
您可能需要,
而不是.
,具体取决于服务器的区域性安装。 Sql Server 2012还有一个新的PARSE()
函数,允许您指定文化,如果升级改变了系统本地文化,则可以消除任何歧义的可能性。
答案 1 :(得分:1)
虽然我并不喜欢以这种方式保存数据,但这听起来是你历史上的原因。 对于SQL Server 2005+(2008+?),您可以转换&#34; varchar&#34;列有效的xml并在其上执行SQL表达式。还有其他可能性,但因此您必须使用过程代码(存储过程/用户定义的函数)和/或临时表ore table变量将日期拆分为表格形式。
因为生成的查询不是那么容易理解,所以我将从一个示例开始,其中varchar类型的变量中包含一个txttotal值的内容。
首先,转换&#34; txttotal&#34;到一个有效的xml片段(您必须添加开始和结束标记,还必须将&#34;,&#34;小数分隔符替换为&#34;。&#34;并将结果转换为XML数据类型。
现在可以选择所有&#34;&#34;节点&#34; ... FROM @ xmltotal.nodes(&#39; / v&#39;)...&#34;从该xml变量中,执行XQuery表达式&#34; ... p.value(&#39;。&#39;,&#39; FLOAT&#39;)...&#34;将它们转换/转换为T-SQL数据类型&#34; FLOAT&#34;最后是值得的SUM()。
DECLARE @txttotal VARCHAR(MAX)
DECLARE @xmltotal XML
SELECT @txttotal = ' 15,50 1,25 10,00 '
SELECT @xmltotal = CAST('<v>'+REPLACE(REPLACE(LTRIM(RTRIM(@txttotal)),',','.'),' ','</v><v>')+'</v>' AS XML)
-- -> <v>15.50</v><v>1.25</v><v>10.00</v>
SELECT SUM(p.value('.', 'FLOAT')) FROM @xmltotal.nodes('/v') t(p)
以上所有内容都可用于编写一个符合您要求的声明性SQL语句......
SELECT (SELECT SUM(p.value('.', 'FLOAT')) FROM xmltotal.nodes('/v') t(p))
FROM
(
SELECT
CAST('<v>'+REPLACE(REPLACE(LTRIM(RTRIM(txttotal)),',','.'),' ','</v><v>')+'</v>' AS XML) AS xmltotal
FROM
Table
-- WHERE
-- add your required condition here!
) T
答案 2 :(得分:0)
首先创建一个拆分字符串函数
CREATE FUNCTION dbo.SplitStrings
(
@List NVARCHAR(MAX),
@Delimiter NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING AS
RETURN
WITH E1(N) AS ( SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1),
E2(N) AS (SELECT 1 FROM E1 a, E1 b),
E4(N) AS (SELECT 1 FROM E2 a, E2 b),
E42(N) AS (SELECT 1 FROM E4 a, E2 b),
cteTally(N) AS (SELECT 0 UNION ALL SELECT TOP (DATALENGTH(ISNULL(@List,1)))
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E42),
cteStart(N1) AS (SELECT t.N+1 FROM cteTally t
WHERE (SUBSTRING(@List,t.N,1) = @Delimiter OR t.N = 0))
SELECT Item = SUBSTRING(@List, s.N1, ISNULL(NULLIF(CHARINDEX(@Delimiter,@List,s.N1),0)-s.N1,8000))
FROM cteStart s;
现在使用cross apply
将值传递给function
并在聚合之前将其拆分。试试这样的事情
SELECT Sum(item) AS Total
FROM table
CROSS apply dbo.Splitstrings(txttotal, ',') sp
WHERE odate BETWEEN x AND y
检查以下链接以创建拆分字符串函数