vijay_bale Ответов: 1

Как использовать union в моей хранимой процедуре MS-SQL


Today I came to know how to use UNION to join tables. Thanks to CHill60. How to use that union in my stored procedure? I will explain my Problem here clearly. I am writing one application for cellphone towers registrations. There some amount we will give to that person like 15000. he is third party registration person like mediator between cell company and site owner. company will take lease site from owner. that mediator person will do the work like registration that lease and all. For that he will charge 3000 like that. some sites are able to register and some not. to calculate the account copy of that mediator like how much amount he took and how much he charged for which site he charged and hoe much balance is like that I have to show. for that I wrote some store procedures to achieve. first I wrote one store procedure to get that result. but not came so I wrote total 7 store procedures for that.
1 for opening balance of that person and 1 for registration and 1 for damage(if registration is not possible he will take expenses) and 1 for opening registrations count and 1 for opening damages site count and one for amount when we gave to that person and how much . all stored procedures with starting and ending dates.

Using union maybe I can reduce that count of procedures.

here my doubt is where I can use union in my store procedure with "where" clause

below I am giving my one store procedure. Here that "@searchparam" I used for dates

USE [registrationDB]
GO
/****** Object:  StoredProcedure [dbo].[repaccopy1data]    Script Date: 11-02-2019 03:17:26 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[repaccopy1data] 
@searchparam		VARCHAR(MAX) =''

AS     
SET NOCOUNT ON  

DECLARE @SqlString  VARCHAR(MAX)  
set @SqlString='select paymentDB.personid
				,paymentDB.pname
				,sum(paymentDB.pamount) as [amount]
				,regstDB.siteid
				,regstDB.rdate
				
				,regstDB.rpid
				,regstDB.totamt
				,regstDB.rperson
				
				from paymentDB  with (NOLOCK) inner join personDB on paymentDB.personid=personDB.pid '

if LTRIM ( RTRIM (@searchparam))<>''

begin
	
	exec (@SqlString + ' where  '+   @searchparam+' group by paymentDB.personid,paymentDB.pname,regstDB.siteid,regstDB.rdate,regstDB.rpid,regstDB.totamt,regstDB.rperson' )

end

else

begin
		EXEC (@SqlString+' group by paymentDB.personid,paymentDB.pname,regstDB.siteid,regstDB.rdate,regstDB.rpid,regstDB.totamt,regstDB.rperson')
		PRINT (@SqlString+' group by paymentDB.personid,paymentDB.pname,regstDB.siteid,regstDB.rdate,regstDB.rpid,regstDB.totamt,regstDB.rperson')
end


print @SqlString + ' where ' + @searchparam+' group by paymentDB.personid,paymentDB.pname,regstDB.siteid,regstDB.rdate,regstDB.rpid,regstDB.totamt,regstDB.rperson'   


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

Я погуглил но не пришел с подходящим результатом

Richard Deeming

@SqlString + ' where  '+   @searchparam+' group by


Прекрасный пример того, почему хранимые процедуры не делают вас невосприимчивыми к SQL-инъекция[^]!

Для выполнения динамического SQL используйте процедуры sp_executesql[^], и передавать параметры как параметры, а не вставлять их в текст команды.

Вам также нужно будет обновить вызывающий код, чтобы передать отдельные параметры, а не полный WHERE пункт.

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

1 Ответов

Рейтинг:
1

Richard MacCutchan

В Google есть много полезной информации: sql union - поиск в Google[^]


vijay_bale

Спасибо. Но я думаю, что вы не прочитали мой вопрос полностью. В своем вопросе я спросил, Где я могу найти пункт "где" в моей процедуре?

Richard MacCutchan

Да, я действительно читал его, но я просто все больше и больше запутывался со всей этой информацией о различных компаниях и их деловой практике. Если вы хотите получить правильный ответ, то вам нужно его предоставить технический подробные сведения о том, что ваши хранимые процедуры должны делать, и какие результаты вы пытаетесь вернуть.

vijay_bale

выше хранилась процедура оплаты, сколько мы дали этому посреднику за регистрацию ( paymentDB) и сколько сайтов он зарегистрировал (regstDB) в некоторые промежуточные даты (для этого я использовал searchparam в качестве параметра)

выше хранимая процедура показала некоторые неправильные результаты, например, он получил оплаченную сумму 15000 и сделал регистрацию 2 означает 2*3000=6000, но эта хранимая процедура дает результаты, подобные 15000 2 раза, поэтому я использовал другую хранимую процедуру для этой цели regstDB(registrations). Вот в этой процедуре я помещаю в комментарии строки типа --regstDB.siteid
--,regstDB.rdate
--,regstDB.rpid
--,regstDB.totamt
--,regstDB.rperson

теперь я получаю правильные результаты, когда выполняю эти 2 процедуры. Если бы я узнал, где мы можем использовать условие "где", то, возможно, я мог бы использовать только одну хранимую процедуру.

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

Richard MacCutchan

Вы можете использовать предложение WHERE где угодно. Это зависит от того, какие элементы информации вам нужно извлечь из базы данных.

MadMyche

Я согласен; хотя некоторый контекст может быть полезен, то, что нам действительно нужно знать, - это техническая сторона этого и бизнес-интеллект, который вы используете, чтобы выбрать, что и где использовать.

vijay_bale

Вышеописанная хранимая процедура предназначена для открытия баланса этого лица

Я вызываю эту хранимую процедуру из языка Си#
// Я читаю pername из выпадающего списка, из которого я читаю perid из personDB.
var searchachist = "personid=" + perid + " и pdate<'" + DBDate(acdt2) + "'"; //принимая конечную дату и вычисляя сумму как открытие

var accopy1 = новая система.Data.DataTable();
using (var cmd = new SqlCommand("repaccopy1data", con))
{
УМК.CommandType = CommandType.Хранимая процедура;
cmd.Parameters.Add("@searchparam", SqlDbType.Text).Значение = searchachist;
var da = новый SqlDataAdapter(cmd);
accopy1 = новая система.Data.DataTable();
da.Fill(accopy1);
против.Закрывать();
}