我需要将参数(@name)
作为字符串传递'Alex','david','crowner'
给存储过程中的查询。
存储过程中的查询如下所示:
select *
from employees
where name in (@name)
将传递的参数值@name
类似于
'Alex','david','crowner'
如何在我的存储过程中处理这个问题,以便在带有IN
运算符的表中查找名称?
我需要将参数(@name)
作为字符串传递'Alex','david','crowner'
给存储过程中的查询。
存储过程中的查询如下所示:
select *
from employees
where name in (@name)
将传递的参数值@name
类似于
'Alex','david','crowner'
如何在我的存储过程中处理这个问题,以便在带有IN
运算符的表中查找名称?
在 SQL Server 2008 及更高版本中,您可以使用表值参数。在数据库中,您必须创建一个表类型。例如:
-- Drop old example definitions
if exists (select * from sys.procedures where name = 'TestProcedure')
drop procedure TestProcedure
if exists (select * from sys.types where name = 'TestTableType')
drop type TestTableType
if exists (select * from sys.tables where name = 'TestTable')
drop table TestTable
go
-- Create example table, type and procedure
create table TestTable (id int identity, name varchar(50))
create type TestTableType as table (name varchar(50))
go
insert TestTable values ('Bill'), ('George'), ('Barrack')
go
create procedure dbo.TestProcedure
@List TestTableType readonly
as
select *
from TestTable
where name in
(
select name
from @List
)
go
在 C# 中,您可以将 aDataTable
作为表值参数传递:
var listTable = new DataTable();
listTable.Columns.Add("Name", typeof(string));
listTable.Rows.Add("Bill");
listTable.Rows.Add("George");
var listParameter = new SqlParameter();
listParameter.ParameterName = "@List";
listParameter.Value = listTable;
using (var con = new SqlConnection("Server=localhost;Database=test;" +
"User Id=testuser;Password=testpassword;"))
{
var com = con.CreateCommand();
com.CommandText = "dbo.TestProcedure";
com.CommandType = CommandType.StoredProcedure;
com.Parameters.Add(listParameter);
con.Open();
using (var read = com.ExecuteReader())
{
while (read.Read())
Console.WriteLine(read["name"]);
}
}
即使是单个表值参数所需的代码量和复杂性也无法满足 SQL Server 设计者的需求。
您可以将单个字符串传递给参数,并在存储过程的主体内使用 charindex 和 substring 等函数并替换为您想要的
经过一番研究,我偶然发现了一个 Code Project 线程,这是解决问题的关键。在上述线程的帮助下,我编写了以下存储过程:
CREATE PROCEDURE [dbo].[myWorkingProcedure]
@inputList nvarchar(MAX)
AS
DECLARE @SetPoint INT
DECLARE @VALUE nvarchar(50)
CREATE TABLE #tempTab (id nvarchar(50) not null)
BEGIN
SET NOCOUNT ON;
WHILE PATINDEX('%,%',@inputList) > 0 <-- Drive loop while commata exist in the input string
BEGIN
SELECT @SetPoint = PATINDEX('%,%',@inputList) <-- Determine position of next comma
SELECT @VALUE = LEFT(@inputList , @SetPoint - 1) <-- copy everything from the left into buffer
SELECT @idList = STUFF(@inputList, 1, @SetPoint, '') <-- throw away the stuff you copied
INSERT INTO #tempTab (id) VALUES (@VALUE) <-- put value in buffer table
END
INSERT INTO #tempTab (id) VALUES (@inputList) <-- insert last value in the input list to buffer
BEGIN
SELECT * FROM myTable
WHERE myColumn IN (SELECT id FROM #tempTab) <-- Do the select
DROP TABLE #tempTab <-- throw buffer table away
END
END
GO