nar86 Ответов: 1

Параметр процедуры хранения не работает


ALTER PROCEDURE [dbo].[sp_get_farmerregistration_by_origin_approveheadid] 
@originname varchar(100),    
@approveheadid varchar(100),    
@mastertype varchar(100),
@farmerctscode varchar(100)    
AS    
BEGIN    
 SET NOCOUNT ON;    
    
 DECLARE @sqlQuery VARCHAR(MAX)    
 DECLARE @masterYear VARCHAR(100)  
      
    SELECT @masterYear =  farmermasteryear FROM tbl_originmanagement WHERE LOWER(REPLACE(@originname,' ','')) = @originname  



IF @mastertype = 'farmerdata'    
 BEGIN    
  SET @sqlQuery = 'SELECT A.*,A.firstname + '' '' + A.lastname + '' '' + A.surname as farmername,B.villagename,    
C.subdistrictname,D.departmentname as districtname,G.zonename,H.name as zonalheadname,M.sectionname,    
I.statusname as zonalheadapprovestatus,J.statusname as regionalheadapprovestatus,    
K.name as zonalheadapprovename,L.name as regionalheadapprovename,    
E.regionname,F.name as regionalheadname    
FROM dbo.tbl_farmerregistration_' + @originname + ' A    
INNER JOIN dbo.tbl_villagemaster_' + @originname + ' B ON B.villageid = A.village    
INNER JOIN dbo.tbl_subdistrictmaster_' + @originname + ' C ON C.subdistrictid = B.subdistrictid    
INNER JOIN dbo.tbl_districtmaster_' + @originname + ' D ON D.districtid = C.districtid    
INNER JOIN dbo.tbl_regionmaster_' + @originname + ' E ON E.regionid = D.regionid    
INNER JOIN dbo.tbl_registration F ON F.regid = E.regionalhead    
INNER JOIN dbo.tbl_sectionmaster_' + @originname + ' M ON M.fieldstaffid = a.createdby    
INNER JOIN dbo.tbl_zonemaster_' + @originname + ' G ON G.zoneid = M.zoneid    
INNER JOIN dbo.tbl_registration H ON H.regid = G.zoneheadid    
INNER JOIN dbo.tbl_approvestatusmaster I ON I.approvestatusid = A.firstlevelapprovalstatus    
INNER JOIN dbo.tbl_approvestatusmaster J ON J.approvestatusid = A.secondlevelapprovalstatus    
LEFT JOIN dbo.tbl_registration K ON K.regid = A.firstlevelapprovedby    
LEFT JOIN dbo.tbl_registration L ON L.regid = A.secondlevelapprovedby   
WHERE H.regid = ''' + @approveheadid + ''' AND A.farmerseason = ''' + @masterYear + '''  order by farmerctscode'    
 END 

 ELSE IF(( @mastertype = 'farmerdata' ) and    ( @farmerctscode = '' ))   
 BEGIN    
  SET @sqlQuery = 'SELECT A.*,A.firstname + '' '' + A.lastname + '' '' + A.surname as farmername,B.villagename,    
C.subdistrictname,D.departmentname as districtname,G.zonename,H.name as zonalheadname,M.sectionname,    
I.statusname as zonalheadapprovestatus,J.statusname as regionalheadapprovestatus,    
K.name as zonalheadapprovename,L.name as regionalheadapprovename,    
E.regionname,F.name as regionalheadname    
FROM dbo.tbl_farmerregistration_' + @originname + ' A    
INNER JOIN dbo.tbl_villagemaster_' + @originname + ' B ON B.villageid = A.village    
INNER JOIN dbo.tbl_subdistrictmaster_' + @originname + ' C ON C.subdistrictid = B.subdistrictid    
INNER JOIN dbo.tbl_districtmaster_' + @originname + ' D ON D.districtid = C.districtid    
INNER JOIN dbo.tbl_regionmaster_' + @originname + ' E ON E.regionid = D.regionid    
INNER JOIN dbo.tbl_registration F ON F.regid = E.regionalhead    
INNER JOIN dbo.tbl_sectionmaster_' + @originname + ' M ON M.fieldstaffid = a.createdby    
INNER JOIN dbo.tbl_zonemaster_' + @originname + ' G ON G.zoneid = M.zoneid    
INNER JOIN dbo.tbl_registration H ON H.regid = G.zoneheadid    
INNER JOIN dbo.tbl_approvestatusmaster I ON I.approvestatusid = A.firstlevelapprovalstatus    
INNER JOIN dbo.tbl_approvestatusmaster J ON J.approvestatusid = A.secondlevelapprovalstatus    
LEFT JOIN dbo.tbl_registration K ON K.regid = A.firstlevelapprovedby    
LEFT JOIN dbo.tbl_registration L ON L.regid = A.secondlevelapprovedby   
WHERE H.regid = ''' + @approveheadid + ''' AND A.farmerseason = ''' + @masterYear + '''  order by farmerctscode'    
 END     

  print(@sqlQuery)
  EXEC(@sqlQuery)    
END


когда я запускаю вышеописанную процедуру хранения вывода я получаю следующее

exec sp_get_farmerregistration_by_origin_approveheadid 'ivorycoast','','farmerdata',''


1875 2019 2010 Рамеш Бабу - мужчина 31-05-1985 Ченнаи Суреш
1975 2019 2010 Суреш Бабу - самец 01-05-1995 Ченнаи Сатиш
1775 2019 2010 Саши Саши - самец 11-08-1995 Ченнаи Сатиш
1675 2019 2010 Srir Sashi - MALE 01-12-1999 Chennai Sathish
1795 2019 2010 Арджун Саши - мужчина 01-07-1989 Ченнаи Сатиш


Bu когда я передаю farmerctscode в процедуре я получаю тот же результат следующим образом

exec sp_get_farmerregistration_by_origin_approveheadid 'ivorycoast','','farmerdata','1875'


1875 2019 2010 Рамеш Бабу - мужчина 31-05-1985 Ченнаи Суреш
1975 2019 2010 Суреш Бабу - самец 01-05-1995 Ченнаи Сатиш
1775 2019 2010 Саши Саши - самец 11-08-1995 Ченнаи Сатиш
1675 2019 2010 Srir Sashi - MALE 01-12-1999 Chennai Sathish
1795 2019 2010 Арджун Саши - мужчина 01-07-1989 Ченнаи Сатиш


когда я передаю farmerctscode в хранимую процедуру мне нужен следующий вывод

exec sp_get_farmerregistration_by_origin_approveheadid 'ivorycoast','','farmerdata','1875'


1875 2019 2010 Рамеш Бабу - мужчина 31-05-1985 Ченнаи Суреш

из моей вышеописанной процедуры хранения, в чем заключается ошибка.

Что я уже пробовал:

см. раздел описание.

Richard Deeming

'... WHERE H.regid = ''' + @approveheadid + ''' AND A.farmerseason = ''' + @masterYear + '''  order by farmerctscode'


Не делай этого так. Вы только что ввели уязвимость SQL-инъекции в хранимую процедуру.

Все, что вы хотели знать о SQL-инъекции (но боялись спросить) | Трой Хант[^]
Как я могу объяснить SQL-инъекцию без технического жаргона? | Обмен Стеками Информационной Безопасности[^]
Шпаргалка по параметризации запросов | OWASP[^]

Параметры всегда должны передаваться в процедуры sp_executesql[^] в качестве параметров.
'... WHERE H.regid = @approveheadid AND A.farmerseason = @masterYear order by farmerctscode'
...
PRINT(@sqlQuery);

EXEC sp_executesql @sqlQuery, 
    N'@approveheadid varchar(100), @masterYear varchar(100)',
    @approveheadid = @approveheadid,
    @masterYear = @masterYear;


Для тех частей, которые не могу передаваемые в качестве параметров, вы должны проверить их до смерти. Никогда не доверяйте ничему, на что может повлиять пользователь!
DECLARE @tbl_farmerregistration sysname;
SELECT @tbl_farmerregistration = QUOTENAME(name) FROM sys.tables WHERE name = N'tbl_farmerregistration_' + @originname;
-- Repeat for all other table names

...


'... FROM dbo.' + @tbl_farmerregistration + ' A ...'

1 Ответов

Рейтинг:
1

Member 7870345

В коде Вашей хранимой процедуры вы создаете в @sqlQuery select stament в зависимости от значения @mastertype и @farmerctscode.
Структура такова

...
IF @mastertype='farmerdata'
   BEGIN
   /*first condition*/
   SET @sqlQuery=bla_bla_bla1
   END
ELSE
   IF ((@master='farmerdata' and  (@farmerctscode='') )
      BEGIN
      /*second condition*/
      SET @sqlQuery=bla_bla_bla2
      END
...


Итак, если @mastertype-это 'farmerdata', то первое условие выполняется, а затем второе условие никогда не оценивается (каким бы ни было значение farmerctscode).

Если вы хотите, чтобы @sqlQuery мог быть adquiere двумя разными значениями, пожалуйста, рассмотрите возможность изменения структуры на что-то вроде:

...
IF ( (@mastertype='farmerdata') and (@farmerctscode<>'') )
   BEGIN
   /*first condition*/
   SET @sqlQuery=bla_bla_bla1
   END
ELSE
   IF ((@mastertype='farmerdata' and  (@farmerctscode='') )
      BEGIN
      /*second condition*/
      SET @sqlQuery=bla_bla_bla2
      END
...



PD: я не могу найти разницу между bla_bla_1 и bla_bla_2