несколько параметров для хранимой процедуры - PullRequest
0 голосов
/ 03 марта 2011

Мне нужно выбрать 45 полей из записи, в которой 96 из них (не спрашивайте меня, но я не могу их нормализовать, я бы, если бы мог). Итак, у меня есть эта страница, на которой будут нужны все эти 45, как только она будет загружена перед пользователем.

По сути, я думал, что создам новый сохраненный процесс, который будет извлекать все имена полей, помещать их в одно поле и все значения и помещать их в другое поле, и в итоге получится два параметра. Затем я бы обработал их в C #.

Теперь мой вопрос: 1, это правильный способ сделать это? Во-вторых, если это не так, я не могу понять, как выбрать поля и поместить их в один параметр.

select @sql = ' select 'field1' + 'field2' + 'field3'.....

я не знаю, с чего начать?

Ответы [ 3 ]

2 голосов
/ 03 марта 2011

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

Вот пример того, как будет выглядеть SQL. Естественно, я не собираюсь вводить 45 столбцов, но вы поняли:

SELECT FirstName, LastName, Age, [keep going to 45] FROM tblUsers

Другая проблема, на которой я хотел бы остановиться, - это способ выполнения оператора SQL. НИКОГДА НИКОГДА НИКОГДА НЕ КОГДА-ЛИБО объединяйте строковые переменные в одну строку SQL. Убедитесь, что вы используете параметризованные запросы как минимум. Но я бы порекомендовал также изучить Entity Framework или LINQ to SQL.

SqlCommand scomm = new SqlCommand("UPDATE tblUsers SET FirstName='" + firstName + "' WHERE UserID='" + userId + "'");

Это ^^^ очень плохо. Подумайте о том, что произойдет, если пользователь решил быть хитрым и сделать свое имя Harry' AND Admin='true. Вы можете подумать: «О, хорошо, я просто сделаю firstName = firstName.Replace("'","''"); для всех моих переменных. Если вы сделаете это, я лично приду к вам. Параметризируйте ваши запросы следующим образом:

SqlCommand scomm = new SqlCommand("UPDATE tblUsers SET FirstName=@FirstName WHERE UserID=@UserID");
scomm.Parameters.Add(new SqlParameter("FirstName", firstName));
scomm.Parameters.Add(new SqlParameter("UserID", userId));

Это ^^^ гораздо лучше.

РЕДАКТИРОВАТЬ Также, если вам когда-нибудь удастся переработать этого монстра из вашей таблицы, попробуйте рефакторинг подмножеств полей в их собственную сущность (таблицу) и связать их через ссылочный идентификатор. Например, скажем, у меня есть таблица с именем [tlbUsers], и она содержит информацию о конкретном пользователе. Как это:

[tlbUsers]
UserID
FirstName
LastName
Age
Username
StreetAddress
City
State
ZipCode
Country
Phone

Рассмотрите возможность рефакторинга, чтобы связанные значения имели свою собственную таблицу. Вы можете взять всю информацию об адресе из этой таблицы пользователей и поместить ее в таблицу с именем tlbAddresses. Это не только облегчит работу при извлечении данных, но и потенциально поможет сэкономить место в базе данных. Например, если Гарри и Салли живут в одном доме, они могут ссылаться на одну и ту же адресную запись.

[tlbUsers]
FirstName
LastName
Age
Username
AddressID
Phone

[tlbAddresses]
AddressID
Street
City
State
ZipCode
Country
0 голосов
/ 04 марта 2011

Вы можете вернуть данные в виде xml в одном поле.

Тестовый стол

create table TestTbl(ID int, F1 int, F2 int, F3 int, F4 int) -- to F96

Данные испытаний

insert into TestTbl values (1, 2, 3, 4, 5)

Запрос

select
  (select
    F1, F2, F3, F4 -- to F45 
   from TestTbl
   where ID = 1
   for xml path('root'), type) as XMLData

Результат

XMLData
-----------------------------------------------------
<root><F1>2</F1><F2>3</F2><F3>4</F3><F4>5</F4></root>

XML в поле XMLData

<root>
  <F1>2</F1>
  <F2>3</F2>
  <F3>4</F3>
  <F4>5</F4>
</root>
0 голосов
/ 03 марта 2011

У меня возникли небольшие проблемы с пониманием вашего вопроса, однако, если вы хотите передать переменное число параметров хранимой процедуре, есть два способа, которыми я могу подумать, что вы можете сделать это, для чего требуются SQL Server 2005 и SQL Server. 2008 соответственно.

Первый использует XML. Пусть ваша процедура принимает аргумент varchar (max), и вы можете легко его разделить. Например, если вы разделяете запятую, что вы хотите, вы можете:

DECLARE @xml xml
SET @xml = cast('<x>'+replace(@yourArg,',','</x><x>')+'</x>' as xml)

SELECT N.value('.','varchar(max)') AS myArgName FROM @xml.nodes('x') AS T(N)

Кроме того, вы можете использовать переменные с табличными значениями, выбрать входные данные в таблицу и передать их в хранимую процедуру. См. http://www.sqlteam.com/article/sql-server-2008-table-valued-parameters для примера.

...