回答

收藏

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

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

我有一个形式的SQL存储过程
, g! i: F) J- ^# f' B  E- k) \SELECT [fields] FROM [table] WHERE @whereSql
9 B& ^* s4 A5 Z. F+ q我想向过程传递一个参数(@whereSql),该参数指定整个WHERE子句,但返回以下错误:
* s2 Q" }/ [- H" nAn expression of non-boolean type specified in a context where a condition is expected
9 [# f) }8 F4 ]7 m4 K! F1 H( D能做到吗?& v* b0 i% V9 k" J
               
7 |9 k6 s4 y. Z/ k* h解决方案:- ], {* B- _1 V
                ! I( |" b6 i9 ?7 ]& T5 G6 s
; C9 S2 U. r9 u$ |0 Q
% A! W7 @9 I9 \
                简短的答案是您不能这样做-SQL Server将变量的内容视为VALUE。它不会动态构建要执行的字符串(这就是为什么这是避免SQL注入攻击的 正确# a) ~; A9 ?1 A9 v
方法)的原因。9 X7 N/ x' m7 u- L/ O" f6 i
您应该尽一切努力避免动态的WHERE,主要是因为这个原因,也是为了提高效率。相反,请尝试建立WHERE子句,以使它根据情况使具有许多OR的部件短路。  m2 d2 a; x. g8 }
如果没有办法解决,您仍然可以根据命令片段构建自己组装的字符串,然后执行。* p4 S4 ?" I& g# V5 c4 Y
因此,您可以这样做:
( u, B+ u, z7 r* L+ U6 @# cDECLARE @mywhere VARCHAR(500)" L( \& K7 A+ f5 ?; T& r$ B2 x8 f
DECLARE @mystmt VARCHAR(1000)
# _, N0 J7 _, B5 |: E, jSET @mywhere = ' WHERE MfgPartNumber LIKE ''a%'' '. ~2 k9 M/ ~" ~" R' t
SELECT @mystmt = 'SELECT TOP 100 * FROM Products.Product AS p ' + @mywhere + ';'
# T' |4 r5 O( z: o% A( ?) ?9 GEXEC( @mystmt ); ?6 b5 B+ d4 j0 _
但我建议您执行以下操作:
2 i, L, g  Z# b6 ^2 eSELECT TOP 100 *
+ a, r3 V3 ~* [) m" j5 f% x, d    FROM Products.Product AS p " ~( ?4 B7 A& |9 h
    WHERE
+ N3 q+ F! I7 s: g        ( MfgPartNumber LIKE 'a%' AND ModeMfrPartNumStartsWith=1)) R4 @% s6 F* O% {
    OR  ( CategoryID = 123 AND ModeCategory=1 )
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则