SQL 中的类型比较

发布于 2024-09-11 00:21:57 字数 956 浏览 10 评论 0原文

我有以下代码作为 SQL 查询的一部分:

INSERT INTO [Database]  
 SELECT DISTINCT @ssId 
   FROM [Document_Map] 
  WHERE (LabelId IN (SELECT Tokens 
                       FROM StringSplitter(@sortValue, '|', 1))

只要 @SortValue 是一个整数,代码就可以正常工作,(LabelId 也是一个 int ) 或由分隔符分隔的整数(例如,SortValue 420|421| 与 420 和 421 进行比较)。但是,我添加的功能涉及 @sortValue 的非整数值。例如:420|ABC|421| 应该与 420、ABC 和 421 进行比较。

不用担心,我想。我将修改该查询的最后一行!

(LabelId IN (SELECT Tokens FROM StringSplitter(@sortValue, '|', 1)) OR 
StringId IN (SELECT Tokens FROM StringSplitter(@sortValue, '|', 1)))

不幸的是,每当我输入包含字符的 @sortValue 时,我都会收到错误。它从未到达的远端。

经过一番研究后,我最终确定 SQL 正在转换 StringSplitter 函数的字符串结果以与 LabelId 进行比较。当保证字符串结果仅包含数字字符时没有问题,但 SQL 拒绝将非数字字符串转换(可以理解)为 int,从而抛出错误。

在保持所需功能的同时解决此错误的最简单方法是什么?由于数据库交互,我不确定更改 LabelId 的类型是否是一个可行的选择。

I've got the following bit of code as part of a SQL Query:

INSERT INTO [Database]  
 SELECT DISTINCT @ssId 
   FROM [Document_Map] 
  WHERE (LabelId IN (SELECT Tokens 
                       FROM StringSplitter(@sortValue, '|', 1))

The code works fine as long as @SortValue is an integer, (LabelId is an int as well) or integers separated by the delimiter character (e.g., SortValue 420|421| compares against 420 and 421). However, I'm adding functionality which involves non-integer values for @sortValue. E.g.: 420|ABC|421| should compare against 420, ABC, and 421.

No worries, I thought. I'll just modify the last line of that query!

(LabelId IN (SELECT Tokens FROM StringSplitter(@sortValue, '|', 1)) OR 
StringId IN (SELECT Tokens FROM StringSplitter(@sortValue, '|', 1)))

Unfortunately, whenever I feed in @sortValue with characters in it, I get an error. It never made it to the far side of the or.

After much mucking around, I finally determined that SQL is casting the string results from the StringSplitter function to compare against LabelId. No problem when the string results were guaranteed to contain only numeric characters, but SQL refuses to cast (understandably) the non-numeric string to an int, throwing out an error.

What's the easiest way to get around this error while maintaining desired functionality? Due to database interaction, I am not sure if changing the type of LabelId is a viable option.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

心凉怎暖 2024-09-18 00:21:57

扩展 DCP 所说的内容,尝试以下代码:

(Convert(varchar(32),LabelId) IN (SELECT Tokens FROM StringSplitter(@sortValue, '|', 1)) OR 
StringId IN (SELECT Tokens FROM StringSplitter(@sortValue, '|', 1)))

只需注意性能问题,在 WHERE 子句中进行转换可能会导致问题......

Expanding on what DCP said, try this code:

(Convert(varchar(32),LabelId) IN (SELECT Tokens FROM StringSplitter(@sortValue, '|', 1)) OR 
StringId IN (SELECT Tokens FROM StringSplitter(@sortValue, '|', 1)))

Just watch out for performance problems, casting in a WHERE clause can cause problems...

不美如何 2024-09-18 00:21:57

我有建议,但也有疑问...

根本原因是 数据类型优先规则。

我不明白的是为什么要将数字列与字符串数据进行比较?为什么要发送非数字数据进行比较?

如果将int LabelID“24”转换为字符串与“024”字符串进行比较,则会失败。当转换为 int 时,字符串“024”变为“24”并且会匹配。您想要和期望什么行为?

我可以理解使用 ISNUMERIC 修复损坏的模式或整理数据,但您似乎是故意发送字符串。

无论如何,您要解决的问题是

  • 更改列类型以匹配您发送的内容,
  • CAST列
  • 从字符串拆分(例如“StringSplitterToInt”)或客户端中的比较中

过滤器字符串,我建议使用数字1来反映您的模型,实际数据或数字 3 来修复你的代码......

I have suggestions but also questions...

The underlying reason is Datatype precedence rules.

What I don't get is why compare a numeric column against string data? Why send non-numeric data for comparison?

If int LabelID "24" cast to string was compared to "024" string, it would fail. String "024" becomes "24" when cast to int though and would match. What behavior do you want and expect?

I can understand fixing a broken schema or tidying data using ISNUMERIC, but you appear to be deliberately sending strings.

Anyhow, you're fixes are

  • change the column type to match what you send
  • CAST the column
  • filter strings out from the comparison either in string split (eg "StringSplitterToInt") or in the client

I'd suggest number 1 to reflect your model and actual data or number 3 to fix your code...

为人所爱 2024-09-18 00:21:57

对于您的功能问题,请尝试 ISNUMERIC:

; WITH data (Foo) AS (
             SELECT '1'
   UNION ALL SELECT 'abc'
)
SELECT
   *
FROM data
WHERE ISNUMERIC(Foo) = 1;

此外,如果您的 Split 函数使用任何其他表(如常见的数字表),请将拆分部分移出 SELECT 语句并将结果存储在临时表中。在语句的 WHERE 部分中调用具有架构绑定的表值函数可能(而且经常)会导致为表的每一行调用该函数。

For your functional problem, try ISNUMERIC:

; WITH data (Foo) AS (
             SELECT '1'
   UNION ALL SELECT 'abc'
)
SELECT
   *
FROM data
WHERE ISNUMERIC(Foo) = 1;

In addition, if your Split function uses any other tables (like a common numbers table), move the split part out of your SELECT statement and store the results in a temp table. Calling a table valued function with schema-binding in the WHERE part of a statement can (and often does) cause a call of the function for each row of your table.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文