[英]SQL Generated Joins with VARCHAR Casting of Decimals
I have a SQL Generator in C# which allows users to pass in parameters which specify a table to join to, and which keys to join on. 我在C#中有一个SQL生成器,它允许用户传递参数,这些参数指定要联接的表以及要联接的键。
Given the flexibility, and the fact that SQL sometimes didn't cast the field appropriately, the query ended up like so: 考虑到灵活性,以及SQL有时无法正确转换字段的事实,查询最终如下所示:
SELECT * FROM [SourceTable] AS [src]
INNER JOIN [JoinTable] [join1] ON CAST([join1].[someField] AS VARCHAR(5000)) = CAST([src].[otherFIeld] AS VARCHAR(5000))
WHERE [blah] = 'blah'
This has worked for quite some time, until it was required that the someField
column on JoinTable
be changed from a float to a decimal. 这已经工作了很长一段时间,直到需要将someField
上的someField
列从浮点数更改为小数点JoinTable
。 So now instead of '1234' = '1234'
working as expected, we get '1234.00000000000' = '1234'
which of course fails. 因此,现在不是'1234' = '1234'
正常工作,而是得到'1234.00000000000' = '1234'
,这当然会失败。
The biggest kink which is stopping me from a quick fix is that that fields don't have to be numeric. 使我无法快速解决问题的最大难题是,字段不必为数字。 They could very well pass in fields that join on lastName
or something, and so I can't just TRY_CONVERT to float or something. 他们可以很好地传递连接在lastName
或其他名称上的字段,因此我不能只是TRY_CONVERT来浮动或其他名称。
The second kink is that this is a join, not just a select, so I don't know the repercussions of putting a bunch of logic in a join, or if that's even possible. 第二个纠结是这是一个联接,而不仅仅是一个选择,所以我不知道在联接中加入一堆逻辑的影响,或者甚至是可能的。 Otherwise I wonder if I could do an IsNumeric type check and, if true, tryconvert to float, then cast to varchar, otherwise just cast to varchar? 否则我想知道是否可以进行IsNumeric类型检查,如果为true,请尝试转换为float,然后转换为varchar,否则仅转换为varchar?
We are using SQL Servers between 2014 and 2016 我们在2014年至2016年之间使用SQL Server
SELECT * FROM [SourceTable] AS [src]
INNER JOIN [JoinTable] [join1]
ON (CASE WHEN isnumeric('join1].[someField]')=1
then CAST(CAST([join1].[someField] AS FLOAT) AS VARCHAR(50))
ELSE
CAST([join1].[someField] AS varchar(50)) end) =
(CASE WHEN isnumeric([src].[otherFIeld])=1 then CAST(CAST([src].
[otherFIeld] AS FLOAT) AS VARCHAR(50))
ELSE CAST([src].[otherFIeld] AS varchar(50)) end)
WHERE [blah] = 'blah'
Otherwise I wonder if I could do an IsNumeric type check and, if true , tryconvert to float, then cast to varchar, otherwise just cast to varchar? 否则我想知道是否可以进行IsNumeric类型检查,如果为true,则尝试转换为float,然后转换为varchar,否则仅转换为varchar?
Yes you have to do it exactly like this.cast both side of join to same data type. 是的,您必须像这样完全做到这一点。将连接的两面都铸造为相同的数据类型。
SELECT * FROM [SourceTable] AS [src]
INNER JOIN [JoinTable] [join1] ON CAST([join1].[someField] AS VARCHAR(5000)) = CAST([src].[otherFIeld] AS VARCHAR(5000))
WHERE [blah] = 'blah' and ISNUMERIC([join1].[someField])=0 and ISNUMERIC([src].[otherFIeld])=0
union ALL
SELECT * FROM [SourceTable] AS [src]
INNER JOIN [JoinTable] [join1] ON CAST([join1].[someField] AS float) = CAST([src].[otherFIeld] AS float)
WHERE [blah] = 'blah' and ISNUMERIC([join1].[someField])=1 and ISNUMERIC([src].[otherFIeld])=1
declare @i decimal(10,4)=1234
declare @ii varchar(400)='1234'
--this won't work
select cast(@i as varchar(400)),@ii
-- this will work
select cast(@i as float),@ii
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.