回答

收藏

通过WHERE子句传递SQL存储过程的整体

技术问答 技术问答 114 人阅读 | 0 人回复 | 2023-09-13

我有一个形式的SQL存储过程# u6 K$ a; u0 F" d9 d' h0 a" U
SELECT [fields] FROM [table] WHERE @whereSql
% X2 t. K1 E+ N我想向过程传递一个参数(@whereSql),该参数指定整个WHERE子句,但返回以下错误:" d5 P' [5 \6 y, }' J- z4 j" r
An expression of non-boolean type specified in a context where a condition is expected
) _7 a6 c7 b# k# |1 `7 _2 i! T1 y能做到吗?
; ^9 ]# u3 }# v, g+ K               
% F0 D+ R2 S! S0 U( E解决方案:
  W! {7 d+ D  T& f                # T0 `$ S0 A9 t5 p; t  h, p
' ?( G6 B4 P6 d4 m2 Q

' u# ^0 z4 `3 ]( K# q; o3 V5 b  G                简短的答案是您不能这样做-SQL Server将变量的内容视为VALUE。它不会动态构建要执行的字符串(这就是为什么这是避免SQL注入攻击的 正确
7 J' y) `: v$ \- \& C6 q7 L! f4 t方法)的原因。, U2 ^; J% Q$ A0 J2 L  f. P! Z$ b
您应该尽一切努力避免动态的WHERE,主要是因为这个原因,也是为了提高效率。相反,请尝试建立WHERE子句,以使它根据情况使具有许多OR的部件短路。
. m3 ~7 _, D# h3 `' m) U如果没有办法解决,您仍然可以根据命令片段构建自己组装的字符串,然后执行。' S+ o+ U3 r  e+ y
因此,您可以这样做:
; B1 V6 T+ U/ k, {) _# CDECLARE @mywhere VARCHAR(500)
6 a4 G  [! t8 X* Y1 p- }DECLARE @mystmt VARCHAR(1000)+ g5 l$ I" S& C
SET @mywhere = ' WHERE MfgPartNumber LIKE ''a%'' '
3 E( X$ N) P2 c9 _. }9 ^5 _SELECT @mystmt = 'SELECT TOP 100 * FROM Products.Product AS p ' + @mywhere + ';'$ Y2 l4 {6 n- J5 L
EXEC( @mystmt )4 l* T) R  H* {  p9 t  G8 k; p- a
但我建议您执行以下操作:
, d7 F5 b4 S! b9 n: @SELECT TOP 100 * : L( x- T# q9 k& v* \# ~
    FROM Products.Product AS p
6 u  p# v  i. w3 c5 e5 U& Q    WHERE
% u, K0 e- e2 Y$ v+ ?* [; |0 l        ( MfgPartNumber LIKE 'a%' AND ModeMfrPartNumStartsWith=1)3 H0 c3 F- d9 r2 X, i
    OR  ( CategoryID = 123 AND ModeCategory=1 )
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则