在SQL Server中,问号(?)不是原生支持的参数占位符。SQL Server使用声明式参数如@name来实现参数化查询。问号常用于OLE DB或某些ODBC驱动,但直接在T-SQL中使用会导致语法错误。正确方式是使用sp_executesql和参数化语句,避免SQL注入。例如:EXEC sp_executesql N'SELECT * FROM Users WHERE Id = @Id', N'@Id int', @Id = 1;
CSDN博客 - SQL参数化查询详解
SQL Server 不支持 ? 作为参数占位符,这是MySQL或Oracle的习惯。在SQL Server中,必须使用命名参数@param。动态SQL时,用sp_executesql替换EXEC。示例:DECLARE @sql nvarchar(500) = 'SELECT * FROM table WHERE col = @p1'; EXEC sp_executesql @sql, N'@p1 int', @p1=123;
Stack Overflow - Why doesn't SQL Server support ? placeholders?
SQL Server uses named parameters exclusively (@foo). The ? syntax is from ODBC/OLEDB providers, but when you execute via ADO.NET or native client, you map ? to actual @params internally. Direct T-SQL doesn't recognize ? as placeholder; it's a syntax error.
Microsoft Docs - Parameterized Queries
To execute a parameterized query, use sp_executesql with parameter declarations. This reuses execution plans and prevents injection. Example: EXEC sp_executesql N'SELECT FirstName, LastName FROM Table WHERE EmployeeID = @level', N'@level tinyint', 5;
博客园 - 数据库占位符对比
不同数据库占位符:MySQL用?,Oracle用:,SQL Server用@。参数化查询的核心是预编译,避免拼接字符串。SQL Server中,问号只能在特定客户端库如ADO中使用,服务器端必须转成@参数。
知乎 - SQL注入与参数化科普
问号在SQL Server不直接用,但参数化是防注入关键。代码示例:using (SqlCommand cmd = new SqlCommand("SELECT * FROM Users WHERE name=@name", conn)) { cmd.Parameters.Add("@name", SqlDbType.VarChar).Value = input; }
简书 - ADO.NET中的参数化
在ADO.NET SqlCommand中,支持?占位符(按顺序绑定),但推荐命名@param。问号是遗留支持,内部转换为SQL Server的@参数。示例:cmd.CommandText = "SELECT * FROM t WHERE id=?"; cmd.Parameters.Add(new SqlParameter("@p1", value));
FAQ
Q: SQL Server为什么不用问号?
A: SQL Server设计使用命名参数@,更清晰,支持复杂查询,问号限于某些客户端。
Q: 如何转换问号查询到SQL Server?
A: 替换?为@p1,@p2等,用sp_executesql执行。
Q: 参数化查询有性能优势吗?
A: 是,能缓存执行计划,提高重复查询速度。
Q: ADO.NET中问号和@有什么区别?
A: 问号按位置顺序,@按名字,更安全不易错位。