基于条件 SQL Server 2012 在语法错误的 WHERE 子句中生成的动态查询附加参数
Generated dynamic query appending parameters in WHERE clause with syntax error based on condition SQL Server 2012
我在 SQL 服务器中有一个查询,使用了 CTE
。每次使用 WHERE clause
中的多个参数触发过程时,都会动态生成查询,并根据具有值的参数附加。问题是因为有多个值要根据条件附加。因此用户可能不传递任何值,则没有WHERE clause
。但是,如果用户传递的所有参数都是任何参数,那么我应该如何使用 and
附加它。因为这个生成的查询有语法错误。我该如何纠正?
declare @vflag varchar(50)=null, @udisecode varchar(20)='1141701604', @district int=null, @zone int=0, @block int=null,
@classid int=null, @className varchar(10)=null, @report varchar(20)=null, @gender varchar(6)=null,
@religion int=null, @category int=null, @subjectid int=null, @subject varchar(30)=null,
@querystr varchar(MAX)=null
set @querystr='
;with cte1 as(
select udise_no,student_regno,fullname,dob,domicile_yesno,admission_date,gender,class_id from tbl_personal
),cte2 as(
select udise_no,student_regno,religion_id,student_category,student_caste from tbl_reservation
),cte3 as(
select categoryname,ID from tbl_category
),cte4 as(
select id,religion from tbl_religion
),cte5 as(
select udisecode,school_name,district_id,block_id from school_master
),cte6 as(
select district_id,district_name from district_master
),cte7 as(
select block_id,block_name,district_id from block_master
)
select a.udise_no, a.fullname as studentname,a.gender,REPLACE(CONVERT(varchar,a.dob,106),'' '',''-'') as dob,
ISNULL(d.categoryname,'''') as category,
ISNULL(c.religion,'''') as religion,
a.domicile_yesno as domicile,a.class_id as class,
a.student_regno,
schoolmaster.school_name,
districtmaster.district_name as district,
blockmaster.block_name
from cte1 a
left join cte2 b
ON b.udise_no=a.udise_no and b.student_regno=a.student_regno
left join cte4 c
on c.ID=b.religion_id
left join cte3 d
on d.ID=b.student_category
left join cte5 schoolmaster
on a.udise_no=schoolmaster.udisecode
left join cte6 districtmaster
on districtmaster.district_id=schoolmaster.district_id
left join cte7 blockmaster
on blockmaster.district_id=districtmaster.district_id and
blockmaster.district_id=schoolmaster.district_id and
blockmaster.block_id=schoolmaster.block_id'
if(@district is not null OR @block is not null OR @udisecode is not null OR
@className is not null OR @category is not null OR @religion is not null OR
@gender is not null)
set @querystr += ' Where '
if(@district is not null)
set @querystr += ' convert(varchar,schoolmaster.district_id) LIKE '''+ISNULL(convert(varchar,@district),'%')+''''
if(@block is not null)
set @querystr += ' and convert(varchar,schoolmaster.block_id) LIKE '''+ISNULL(convert(varchar,@block),'%')+''''
if(@udisecode is not null)
set @querystr += ' and a.udise_no LIKE '''+ISNULL(@udisecode,'%')+''''
if(@className is not null)
set @querystr += ' and a.class_id LIKE '''+ISNULL(@className,'%')+''''
if(@category is not null)
set @querystr += ' and CONVERT(varchar,b.student_category) LIKE '''+ISNULL(CONVERT(varchar,@category),'%')+''''
if(@religion is not null)
set @querystr += ' and CONVERT(varchar,b.religion_id) LIKE '''+ISNULL(CONVERT(varchar,@religion),'%')+''''
if(@gender is not null)
set @querystr += ' and a.gender LIKE '''+ISNULL(@gender,'%')+''''
set @querystr += ' order by districtmaster.district_name,blockmaster.block_name'
print(@querystr)
--exec(@querystr)
语法错误:
Where and a.udise_no LIKE '1141701604' order by districtmaster.district_name,blockmaster.block_name
人们使用 where 1 = 1
是因为他们在构建动态 SQL 查询时天生懒惰。如果您以 where 1 = 1
开头,那么您所有的额外子句都将以 AND
开头,您不必弄清楚。
查询应该是
DECLARE @vflag VARCHAR(50) = NULL,
@udisecode VARCHAR(20) = '1141701604',
@district INT = NULL,
@zone INT = 0,
@block INT = NULL,
@classid INT = NULL,
@className VARCHAR(10) = NULL,
@report VARCHAR(20) = NULL,
@gender VARCHAR(6) = NULL,
@religion INT = NULL,
@category INT = NULL,
@subjectid INT = NULL,
@subject VARCHAR(30) = NULL,
@querystr VARCHAR(MAX) = NULL
SET @querystr = '
;with cte1 AS(
SELECT udise_no,student_regno,fullname,dob,domicile_yesno,admission_date,gender,class_id from tbl_personal
),cte2 AS(
SELECT udise_no,student_regno,religion_id,student_category,student_caste from tbl_reservation
),cte3 AS(
SELECT categoryname,ID from tbl_category
),cte4 AS(
SELECT id,religion from tbl_religion
),cte5 AS(
SELECT udisecode,school_name,district_id,block_id from school_master
),cte6 AS(
SELECT district_id,district_name from district_master
),cte7 AS(
SELECT block_id,block_name,district_id from block_master
)
SELECT a.udise_no, a.fullname AS studentname,a.gender,REPLACE(CONVERT(VARCHAR,a.dob,106),'' '',''-'') AS dob, ISNULL(d.categoryname,'''') AS category,
ISNULL(c.religion,'''') AS religion, a.domicile_yesno AS domicile,a.class_id AS class, a.student_regno, schoolmaster.school_name,
districtmaster.district_name AS district, blockmaster.block_name
FROM cte1 a LEFT JOIN cte2 b ON b.udise_no = a.udise_no AND b.student_regno = a.student_regno
LEFT JOIN cte4 c ON c.ID = b.religion_id
LEFT JOIN cte3 d ON d.ID = b.student_category
LEFT JOIN cte5 schoolmaster ON a.udise_no = schoolmaster.udisecode
LEFT JOIN cte6 districtmaster ON districtmaster.district_id = schoolmaster.district_id
LEFT JOIN cte7 blockmaster ON blockmaster.district_id = districtmaster.district_id AND blockmaster.district_id = schoolmaster.district_id AND blockmaster.block_id = schoolmaster.block_id'
IF(@district IS NOT NULL OR @block IS NOT NULL OR @udisecode IS NOT NULL OR @className IS NOT NULL OR @category IS NOT NULL OR @religion IS NOT NULL OR @gender IS NOT NULL)
SET @querystr += ' WHERE 1 = 1'
IF(@district IS NOT NULL)
SET @querystr += 'AND convert(VARCHAR,schoolmaster.district_id) LIKE '''+ISNULL(convert(VARCHAR,@district),'%')+''''
IF(@block IS NOT NULL)
SET @querystr += ' AND convert(VARCHAR,schoolmaster.block_id) LIKE '''+ISNULL(convert(VARCHAR,@block),'%')+''''
IF(@udisecode IS NOT NULL)
SET @querystr += ' AND a.udise_no LIKE '''+ISNULL(@udisecode,'%')+''''
IF(@className IS NOT NULL)
SET @querystr += ' AND a.class_id LIKE '''+ISNULL(@className,'%')+''''
IF(@category IS NOT NULL)
SET @querystr += ' AND CONVERT(VARCHAR,b.student_category) LIKE '''+ISNULL(CONVERT(VARCHAR,@category),'%')+''''
IF(@religion IS NOT NULL)
SET @querystr += ' AND CONVERT(VARCHAR,b.religion_id) LIKE '''+ISNULL(CONVERT(VARCHAR,@religion),'%')+''''
IF(@gender IS NOT NULL)
SET @querystr += ' AND a.gender LIKE '''+ISNULL(@gender,'%')+''''
SET @querystr += ' order by districtmaster.district_name,blockmaster.block_name'
PRINT(@querystr)
EXEC (@querystr)
我在 SQL 服务器中有一个查询,使用了 CTE
。每次使用 WHERE clause
中的多个参数触发过程时,都会动态生成查询,并根据具有值的参数附加。问题是因为有多个值要根据条件附加。因此用户可能不传递任何值,则没有WHERE clause
。但是,如果用户传递的所有参数都是任何参数,那么我应该如何使用 and
附加它。因为这个生成的查询有语法错误。我该如何纠正?
declare @vflag varchar(50)=null, @udisecode varchar(20)='1141701604', @district int=null, @zone int=0, @block int=null,
@classid int=null, @className varchar(10)=null, @report varchar(20)=null, @gender varchar(6)=null,
@religion int=null, @category int=null, @subjectid int=null, @subject varchar(30)=null,
@querystr varchar(MAX)=null
set @querystr='
;with cte1 as(
select udise_no,student_regno,fullname,dob,domicile_yesno,admission_date,gender,class_id from tbl_personal
),cte2 as(
select udise_no,student_regno,religion_id,student_category,student_caste from tbl_reservation
),cte3 as(
select categoryname,ID from tbl_category
),cte4 as(
select id,religion from tbl_religion
),cte5 as(
select udisecode,school_name,district_id,block_id from school_master
),cte6 as(
select district_id,district_name from district_master
),cte7 as(
select block_id,block_name,district_id from block_master
)
select a.udise_no, a.fullname as studentname,a.gender,REPLACE(CONVERT(varchar,a.dob,106),'' '',''-'') as dob,
ISNULL(d.categoryname,'''') as category,
ISNULL(c.religion,'''') as religion,
a.domicile_yesno as domicile,a.class_id as class,
a.student_regno,
schoolmaster.school_name,
districtmaster.district_name as district,
blockmaster.block_name
from cte1 a
left join cte2 b
ON b.udise_no=a.udise_no and b.student_regno=a.student_regno
left join cte4 c
on c.ID=b.religion_id
left join cte3 d
on d.ID=b.student_category
left join cte5 schoolmaster
on a.udise_no=schoolmaster.udisecode
left join cte6 districtmaster
on districtmaster.district_id=schoolmaster.district_id
left join cte7 blockmaster
on blockmaster.district_id=districtmaster.district_id and
blockmaster.district_id=schoolmaster.district_id and
blockmaster.block_id=schoolmaster.block_id'
if(@district is not null OR @block is not null OR @udisecode is not null OR
@className is not null OR @category is not null OR @religion is not null OR
@gender is not null)
set @querystr += ' Where '
if(@district is not null)
set @querystr += ' convert(varchar,schoolmaster.district_id) LIKE '''+ISNULL(convert(varchar,@district),'%')+''''
if(@block is not null)
set @querystr += ' and convert(varchar,schoolmaster.block_id) LIKE '''+ISNULL(convert(varchar,@block),'%')+''''
if(@udisecode is not null)
set @querystr += ' and a.udise_no LIKE '''+ISNULL(@udisecode,'%')+''''
if(@className is not null)
set @querystr += ' and a.class_id LIKE '''+ISNULL(@className,'%')+''''
if(@category is not null)
set @querystr += ' and CONVERT(varchar,b.student_category) LIKE '''+ISNULL(CONVERT(varchar,@category),'%')+''''
if(@religion is not null)
set @querystr += ' and CONVERT(varchar,b.religion_id) LIKE '''+ISNULL(CONVERT(varchar,@religion),'%')+''''
if(@gender is not null)
set @querystr += ' and a.gender LIKE '''+ISNULL(@gender,'%')+''''
set @querystr += ' order by districtmaster.district_name,blockmaster.block_name'
print(@querystr)
--exec(@querystr)
语法错误:
Where and a.udise_no LIKE '1141701604' order by districtmaster.district_name,blockmaster.block_name
人们使用 where 1 = 1
是因为他们在构建动态 SQL 查询时天生懒惰。如果您以 where 1 = 1
开头,那么您所有的额外子句都将以 AND
开头,您不必弄清楚。
查询应该是
DECLARE @vflag VARCHAR(50) = NULL,
@udisecode VARCHAR(20) = '1141701604',
@district INT = NULL,
@zone INT = 0,
@block INT = NULL,
@classid INT = NULL,
@className VARCHAR(10) = NULL,
@report VARCHAR(20) = NULL,
@gender VARCHAR(6) = NULL,
@religion INT = NULL,
@category INT = NULL,
@subjectid INT = NULL,
@subject VARCHAR(30) = NULL,
@querystr VARCHAR(MAX) = NULL
SET @querystr = '
;with cte1 AS(
SELECT udise_no,student_regno,fullname,dob,domicile_yesno,admission_date,gender,class_id from tbl_personal
),cte2 AS(
SELECT udise_no,student_regno,religion_id,student_category,student_caste from tbl_reservation
),cte3 AS(
SELECT categoryname,ID from tbl_category
),cte4 AS(
SELECT id,religion from tbl_religion
),cte5 AS(
SELECT udisecode,school_name,district_id,block_id from school_master
),cte6 AS(
SELECT district_id,district_name from district_master
),cte7 AS(
SELECT block_id,block_name,district_id from block_master
)
SELECT a.udise_no, a.fullname AS studentname,a.gender,REPLACE(CONVERT(VARCHAR,a.dob,106),'' '',''-'') AS dob, ISNULL(d.categoryname,'''') AS category,
ISNULL(c.religion,'''') AS religion, a.domicile_yesno AS domicile,a.class_id AS class, a.student_regno, schoolmaster.school_name,
districtmaster.district_name AS district, blockmaster.block_name
FROM cte1 a LEFT JOIN cte2 b ON b.udise_no = a.udise_no AND b.student_regno = a.student_regno
LEFT JOIN cte4 c ON c.ID = b.religion_id
LEFT JOIN cte3 d ON d.ID = b.student_category
LEFT JOIN cte5 schoolmaster ON a.udise_no = schoolmaster.udisecode
LEFT JOIN cte6 districtmaster ON districtmaster.district_id = schoolmaster.district_id
LEFT JOIN cte7 blockmaster ON blockmaster.district_id = districtmaster.district_id AND blockmaster.district_id = schoolmaster.district_id AND blockmaster.block_id = schoolmaster.block_id'
IF(@district IS NOT NULL OR @block IS NOT NULL OR @udisecode IS NOT NULL OR @className IS NOT NULL OR @category IS NOT NULL OR @religion IS NOT NULL OR @gender IS NOT NULL)
SET @querystr += ' WHERE 1 = 1'
IF(@district IS NOT NULL)
SET @querystr += 'AND convert(VARCHAR,schoolmaster.district_id) LIKE '''+ISNULL(convert(VARCHAR,@district),'%')+''''
IF(@block IS NOT NULL)
SET @querystr += ' AND convert(VARCHAR,schoolmaster.block_id) LIKE '''+ISNULL(convert(VARCHAR,@block),'%')+''''
IF(@udisecode IS NOT NULL)
SET @querystr += ' AND a.udise_no LIKE '''+ISNULL(@udisecode,'%')+''''
IF(@className IS NOT NULL)
SET @querystr += ' AND a.class_id LIKE '''+ISNULL(@className,'%')+''''
IF(@category IS NOT NULL)
SET @querystr += ' AND CONVERT(VARCHAR,b.student_category) LIKE '''+ISNULL(CONVERT(VARCHAR,@category),'%')+''''
IF(@religion IS NOT NULL)
SET @querystr += ' AND CONVERT(VARCHAR,b.religion_id) LIKE '''+ISNULL(CONVERT(VARCHAR,@religion),'%')+''''
IF(@gender IS NOT NULL)
SET @querystr += ' AND a.gender LIKE '''+ISNULL(@gender,'%')+''''
SET @querystr += ' order by districtmaster.district_name,blockmaster.block_name'
PRINT(@querystr)
EXEC (@querystr)