C# SQL 2005/2008中的转义双引号

C# SQL 2005/2008中的转义双引号,c#,sql,sql-server,full-text-search,C#,Sql,Sql Server,Full Text Search,我最近加入了一家国际公司,名为“BLA”BLAHBLAH“Ltd(双引号是名称的一部分) 每当用户试图搜索该公司时,通过输入“Blah”或类似内容,搜索就会失败,SQL server中出现语法错误 我怎样才能避免这种情况,使搜索不会失败 示例SQL: SELECT c.companyID, c.companyName, c.dateAdded, count(cm.maxID) as NumDirect FROM RussoundGeneral.dbo.Company c

我最近加入了一家国际公司,名为“BLA”BLAHBLAH“Ltd(双引号是名称的一部分)

每当用户试图搜索该公司时,通过输入“Blah”或类似内容,搜索就会失败,SQL server中出现语法错误

我怎样才能避免这种情况,使搜索不会失败

示例SQL:

SELECT c.companyID, c.companyName, c.dateAdded, count(cm.maxID) as NumDirect
    FROM RussoundGeneral.dbo.Company c  
         LEFT JOIN RussoundGeneral.dbo.CompanyMax cm
                ON (cm.companyId = c.companyId and cm.maxID is not null)  
    WHERE CONTAINS ( companyName,  '"BLAH*' )
    GROUP BY c.companyID, c.companyName, c.dateAdded  
    ORDER BY c.companyName ASC

我强烈怀疑您正在动态构建SQL—例如

// Bad code, do not use!
string sql = "SELECT * FROM Foo WHERE X LIKE '" + input + "%'";
这是一个非常非常糟糕的主意,原因很多——最明显的是。改为使用参数化SQL语句,其中单独指定参数


查看问题的各种答案,以了解如何正确执行此操作。

使用参数化查询,您的所有引用难题都将消失


编辑:如果不允许他们在CONTAINS中输入多个单词,请通过删除引号来清理参数。不管多词搜索如何,通过删除引号来清理输入可能会起到任何作用。

不幸的是,双引号在FTI中具有特殊意义,因此即使您对其进行参数化,FTI引擎也会将其视为短语分隔符。我不确定是否有一种简单的方法可以在FTI搜索中包含双引号。方括号也是一个特殊字符,但可以用引号括起来作为查询词,但不能用双引号括起来

更新

稍微搜索一下就可以发现,将引号加倍到“”可能会解决这个问题,值得一试。就我个人而言,我会在DB中这样做,因为这是一个TSQL实现细节


同样,在传递到FTI(完全独立于TSQL转义)之前,“需要加倍到“”,

您是否尝试过用ASCII码替换字符

尝试使用转义关键字:

SELECT c.companyID, c.companyName, c.dateAdded, count(cm.maxID) as NumDirect 
FROM RussoundGeneral.dbo.Company c          
LEFT JOIN RussoundGeneral.dbo.CompanyMax cm 
ON (cm.companyId = c.companyId and cm.maxID is not null )  
WHERE CONTAINS ( companyName,  '\"BLAH*' ) escape '\'
group by c.companyID, c.companyName, c.dateAdded  ORDER BY c.companyName ASC

应该是

string sqlCommand = "SELECT c.companyID, c.companyName, c.dateAdded, count(cm.maxID) as NumDirect FROM RussoundGeneral.dbo.Company c LEFT JOIN RussoundGeneral.dbo.CompanyMax cm ON (cm.companyId = c.companyId and cm.maxID is not null ) WHERE CONTAINS ( companyName,  '@strVal' ) group by c.companyID, c.companyName, c.dateAdded ORDER BY c.companyName ASC"
SqlCommand command = new SqlCommand(strSQLCommand, conn); 
SqlCommand.Parameters.AddWithValue("@strval", SearchTextBox.Text); 

这是一个有点理论性的答案,但可能会有所帮助。简短的版本是“在查询中使用参数”,但它有助于理解完整的细节

在标准SQL中,字符串用单引号括起来,嵌入的单引号由一行中的两个单引号表示:

SELECT * FROM SomeWhere
    WHERE SomeThing = 'He said, "Don''t do it!"';
在SQL的某些方言中,您可以使用双引号关闭字符串;然后需要将双引号加倍,以嵌入双引号的单个实例:

SELECT * FROM SomeWhere
    WHERE SomeThing = "He said, ""Don't do it!""';
这个问题不清楚公司名称是否包含外部双引号以及中间双引号,或者是否只包含中间双引号。但是,原则上,规则是相同的。假设所有三个双引号都是必需的,并且在SQL中使用单引号-在这种情况下更容易:

SELECT c.companyID, c.companyName, c.dateAdded, count(cm.maxID) as NumDirect
    FROM RussoundGeneral.dbo.Company c  
         LEFT JOIN RussoundGeneral.dbo.CompanyMax cm
                ON (cm.companyId = c.companyId and cm.maxID is not null)  
    WHERE CONTAINS ( companyName,  '"BLAH "BLAHBLAH" Ltd.' )
    GROUP BY c.companyID, c.companyName, c.dateAdded  
    ORDER BY c.companyName ASC;
使用双引号:

SELECT c.companyID, c.companyName, c.dateAdded, count(cm.maxID) as NumDirect
    FROM RussoundGeneral.dbo.Company c  
         LEFT JOIN RussoundGeneral.dbo.CompanyMax cm
                ON (cm.companyId = c.companyId and cm.maxID is not null)  
    WHERE CONTAINS ( companyName,  """BLAH ""BLAHBLAH"" Ltd." )
    GROUP BY c.companyID, c.companyName, c.dateAdded  
    ORDER BY c.companyName ASC;
如果您在编程语言中构建字符串,那么您必须担心这些引号是否超过了在编程语言中计算字符串的值。例如,如果在C中构建字符串文字,则必须用反斜杠转义双引号:

static const char sql_stmt[] =
"SELECT c.companyID, c.companyName, c.dateAdded,\n"
"       COUNT(cm.maxID) AS NumDirect\n"
"    FROM RussoundGeneral.dbo.Company c\n"
"         LEFT JOIN RussoundGeneral.dbo.CompanyMax cm\n"
"                ON (cm.companyId = c.companyId AND cm.maxID IS NOT NULL)\n"  
"    WHERE CONTAINS(companyName,  \"\"\"BLAH \"\"BLAHBLAH\"\" Ltd.\")\n"
"    GROUP BY c.companyID, c.companyName, c.dateAdded\n"
"    ORDER BY c.companyName ASC";
另一方面,如果您从用户处读取数据,例如公司名称,那么您只需确保所读取的数据被正确引用即可

那些说“使用参数”的人是对的——它更容易、更可靠,更不容易受到SQL注入攻击(看看您是否还没有看到它)。但是,如果您了解基本原理,就可以适应系统的实际需求


最后一点注意:在标准SQL中,双引号将“分隔标识符”括起来。也就是说,双引号围绕着一个名称,该名称必须被视为数据库中某个对象的名称,而不是字符串文字。在MS SQL Server中,[方括号]具有相同的用途;括号之间是列的名称或数据库中的任何内容。许多系统比这更灵活;并非所有系统在偏离标准方面都是相同的。

您最终必须从数据库中提取数据,并将其显示在屏幕上或打印在报告上。操纵双引号或任何额外的字符可能会变得非常混乱

通过在插入或更新之前将字符串转换为HTML,可以避免与报价管理相关的所有混乱。在选定的时间,将很容易从HTML转换回来。在报告时(由于报告工具(如Crystal Reports)提出了HTML格式选项),您甚至不必做任何事情来正确显示数据


顺便说一句,别忘了绞死发明这个公司名称的人

抱歉,但是没有。在这里,集中sql会让你在口头上被打败。。。。。是我。我不会容忍它们。t-SQL中的字符串操作速度慢得令人难以置信。如果查询经常被调用,他最好在调用之前修复数据库外的引号。刚刚在Sql2014上测试过-双引号确实有效。这个问题为我解决了。谢谢