【问题标题】:SQL Argument data type int is invalid for argument 1 of charindex functionSQL 参数数据类型 int 对 charindex 函数的参数 1 无效
【发布时间】:2016-07-29 06:18:54
【问题描述】:

我正在尝试将 MySQL 查询转换为 MsSql 查询,但我遇到了问题。这是我的查询:

MySQL

SELECT *,
(SELECT count(books.id)
   FROM books
   WHERE books.status = 1
     AND FIND_IN_SET(categories.id, books.multiple_category_id)) AS book_count
   FROM categories, books
   WHERE categories.parent_id=0
     AND categories.status=1 ;

我试过的 SQL

SELECT *,
  (SELECT count(books.id)
   FROM books
   WHERE books.status = 1
     AND CHARINDEX(categories.id, books.multiple_category_id) > 0) AS book_count
   FROM categories, books
   WHERE categories.parent_id=0
     AND categories.status=1 ;

我得到的错误是:

Argument data type int is invalid for argument 1 of charindex function.

供参考。 http://sqlfiddle.com/#!3/4ed19/3

有人有什么想法吗? 提前致谢!

【问题讨论】:

    标签: php mysql sql sql-server


    【解决方案1】:

    使用此查询。我刚刚将categories.id 更改为CAST(categories.id AS VARCHAR)。因为idcategories 表中是integer

    SELECT *,
    (SELECT count(books.id)
       FROM books
       WHERE books.status = 1
         AND CHARINDEX(CAST(categories.id AS VARCHAR), books.multiple_category_id) > 0) AS book_count
    FROM categories,
         books
    WHERE categories.parent_id=0
      AND categories.status=1 ;
    

    【讨论】:

    • 感谢您抽出宝贵的时间来回答这个问题.. 荣誉
    • 有什么理由拒绝投票?
    【解决方案2】:

    MS-SQLCHARINDEX 函数需要 VARCHAR 或 NVARCHAR 作为参数,因此您的 categories.id 应转换为 VARCHAR。像这样的:

    CHARINDEX(CAST(categories.id AS VARCHAR(16)), books.multiple_category_id ) > 0 )
    

    但是,我会考虑重构表和您的查询:

    1.查询重构

    正如它所写的,你可以有错误的匹配。例如。 categories.id = 1 而你的 multiple_category_id'11,12'split your string 的替代方法是让您的条件如下:

    AND EXISTS (SELECT 1 FROM dbo.SplitString(books.multiple_category_id) WHERE Token = categories.id)
    

    此外,* 应该替换为实际需要的列(在这种情况下,它将带来两个表中的所有列)。像这样的:

    2。表重构

    您应该像这样定义一个 X 表,而不是解析字符串:

    categoryXbook

    categoryId FK 参考类别 bookId FK 参考书 主键(categoryId、bookId)

    因此,您可以使用简单的JOINs 进行查询,而不是使用速度较慢的字符串搜索(不能使用索引)。

    【讨论】:

      【解决方案3】:

      这是另一种方法

      SELECT *,
             (SELECT Count(books.id)
              FROM   books
              WHERE  books.status = 1
                     AND ',' + books.multiple_category_id + ',' LIKE '%,' + cast(categories.id as varchar(50))+ ',%') AS book_count
      FROM   categories,
             books
      WHERE  categories.parent_id = 0
             AND categories.status = 1; 
      

      注意:在您的查询中,categoriesbooks 表之间存在笛卡尔积。我猜你在From 子句中不需要books。停止在违反第一范式的列中存储逗号分隔值

      【讨论】:

      • 将 varchar 值 '%,' 转换为数据类型 int 时转换失败。
      • @Chinnu - 现在更新检查