Возврат нескольких значений из хранимой процедуры SQL Server

93
3

То, что я хотел бы сделать, это использовать мою хранимую процедуру spLogin для возврата двух значений из одной и той же таблицы, оба из которых я хотел бы сохранить в сеансах на С#.

Вот таблица

create table tbClients
(
ClientID int primary key identity(0,1),
ClientFirstName varchar(20),
ClientLastName varchar(20),
ClientAddress varchar(60),
ClientOrigin varchar(20),
ClientUsername varchar(20),
ClientPassword int,
ClientSecurity int
)

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

Вот что я до сих пор

create procedure spLogin(
@ClientUsername varchar(20),
@ClientPassword int
)
AS BEGIN
DECLARE @Security int
DECLARE @ClientFirstName varchar(20)

IF EXISTS (SELECT * FROM tbClients
WHERE ClientUsername = @ClientUsername
AND ClientPassword = @ClientPassword)
BEGIN
SELECT
@Security = ClientSecurity,
@ClientFirstName = ClientFirstName
FROM tbClients
WHERE
ClientUsername = @ClientUsername
AND ClientPassword = @ClientPassword

IF(@Security = 1)
BEGIN
SELECT 'Admin' as Security, @ClientFirstName
END
ELSE
BEGIN
SELECT 'Customer' as Security, @ClientFirstName
END
END
ELSE
BEGIN
SELECT 'INVALID'
END
END
GO

Не знаю, будет ли это работать, потому что я не уверен, как сохранить эти значения на С# без использования набора данных, который пока не работает?

спросил(а) 2021-01-14T00:17:32+03:00 2 недели назад
1
Решение
94

Я бы написал эту процедуру немного иначе, чем это.....

create procedure spLogin
@ClientUsername varchar(20)
,@ClientPassword int
,@Security VARCHAR(10) OUTPUT
,@ClientFirstName varchar(20) OUTPUT
,@ValidLogin INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;

IF EXISTS (SELECT * FROM tbClients
WHERE ClientUsername = @ClientUsername
AND ClientPassword = @ClientPassword)
BEGIN
SELECT @ValidLogin = 1
,@Security = CASE WHEN ClientSecurity = 1
THEN 'Admin' ELSE 'Customer' END
,@ClientFirstName = ClientFirstName
FROM tbClients
WHERE ClientUsername = @ClientUsername
AND ClientPassword = @ClientPassword
END
ELSE
BEGIN
SET @ValidLogin = 0;
END
END
GO

Не эксперт С#, но вы бы обрабатывали выходные параметры в С#, что-то вроде....

// define connection and command, in using blocks to ensure disposal
using(SqlConnection conn = new SqlConnection(pvConnectionString ))
using(SqlCommand cmd = new SqlCommand("dbo.spLogin", conn))
{
cmd.CommandType = CommandType.StoredProcedure;

// set up the input parameters
cmd.Parameters.Add("@ClientUsername", SqlDbType.VarChar, 20);
cmd.Parameters.Add("@ClientPassword", SqlDbType.Int);
cmd.Parameters.Add("@Security", SqlDbType.VarChar, 10).Direction = ParameterDirection.Output;
cmd.Parameters.Add("@ClientFirstName", SqlDbType.VarChar, 20).Direction = ParameterDirection.Output;
cmd.Parameters.Add("@Success", SqlDbType.Int).Direction = ParameterDirection.Output;

// set parameter values
cmd.Parameters["@ClientUsername"].Value = UserNamTextbox.Text;

// open connection and execute stored procedure
conn.Open();
cmd.ExecuteNonQuery();

// read output value from @Security
int Security = Convert.ToInt32(cmd.Parameters["@Security"].Value);

if Security == 1 ....... and so on.......

conn.Close();
}

ответил(а) 2021-01-14T00:17:32+03:00 2 недели назад
43

В результате ваша процедура магазина возвращает только одну строку, вы можете проверить, существует ли столбец в datatable:

if (dt.columns.Contains("Security"))
{
....
}else{
// Show error in fist row, fist column
return dt.Rows[0][0].ToString();
}

ответил(а) 2021-01-14T00:17:32+03:00 2 недели назад
43

Вы можете выполнить хранимую процедуру и заполнить результат в наборе данных.

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

ответил(а) 2021-01-14T00:17:32+03:00 2 недели назад
43

поэтому я не уверен на 100%, сколько из С# у вас на вашем конце, но вот основные сведения:

Используйте код в этом вопросе SO для получения данных с SQL Server: Заполните DataTable из базы данных SQL Server

Затем, как только у вас будет свой datatable, вы можете пропустить его с помощью цикла for так, чтобы (если бы вы определили свой Datatable как 'dt'):

foreach (DataRow row in dt.Rows) 
{
//do what you need with your data.
var value = row["ColumnName"];
Console.WriteLine(value.ToString());
}

Надеюсь, это поможет.

ответил(а) 2021-01-14T00:17:32+03:00 2 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема