SQL Server 2017 Table 值函数 - 使用多个值而不是一个值进行过滤
SQL Server 2017 Table-valued Functions - filtering with multiple values instead of just one
我正在使用 SQL Server 2017,版本 14.0.2002.14
(开发版(64 位))
我正在尝试创建一个函数,用户可以在其中传递多个值来过滤查询。
我通常可以使用只需要一个参数的函数来完成,使用下面的模板:
CREATE FUNCTION func_1
(
@StartDate date,
@EndDate date
)
RETURNS TABLE AS
RETURN
(
SELECT * FROM table_name
WHERE table_name.Date BETWEEN @StartDate and @EndDate
)
用户可以通过以下操作return过滤结果:
SELECT * FROM func_1('20190101', '20191231')
当尝试通过传入多个值来 return 结果时,此查询在 SQL 服务器上执行时有效:
-- Declare a TABLE variable to be used as a filter
DECLARE @Product TABLE
(
Products varchar(10)
)
INSERT INTO @Product VALUES('value_1', 'value_2')
-- Return filtered results from query
SELECT Date, Product, Quantity
FROM Table_Name
WHERE Table_Name.Product IS IN (SELECT Products FROM @Product)
但是,我想将它创建为一个函数,SQL 服务器不喜欢...
CREATE FUNCTION func_2
(
@StartDate date,
@EndDate date,
@Product TABLE
(
Product varchar(10)
)
INSERT INTO @Product VALUES()
)
RETURNS TABLE AS
RETURN
(
SELECT Date, Product, Quantity
FROM Table_Name
WHERE Date BETWEEN @StartDate AND @EndDate
AND Table_Name.Product IS IN (SELECT Products FROM @Product)
)
用户应调用此查询并获得 return 过滤结果:
SELECT * FROM func_2('20190101', '20191231', ('value_1', 'value_2', 'value_3'))
编辑:也向 func_2 添加了日期参数,即该函数的预期用途是根据 1 个以上的参数进行过滤
我做过类似的事情。您必须创建一个 table 类型,它将是一个字符串列表。例如:
CREATE TYPE FilterType AS TABLE (MyFilter VARCHAR(10))
然后,您可以在存储过程中指定此参数(函数错误不可用我认为它无论如何都会用存储过程执行您想要的操作)。
CREATE PROCEDURE MyProc (@filters FilterType READONLY, ...)
进入程序后,您可以将其用作 table
SELECT * FROM YourTable t join @filters f on f.MyFilter = t.Column
这样做的好处是您可以根据需要定义 TYPE 并根据需要向其添加任意数量的参数。
以下link中的内容与您想要实现的功能相同,但仅针对一个参数。
sql-server-user-defined-functions
CREATE FUNCTION udfProductInYear (
@model_year INT
)
RETURNS TABLE
AS
RETURN
SELECT
product_name,
model_year,
list_price
FROM
production.products
WHERE
model_year = @model_year;
访问您的函数时,请使用以下内容:
SELECT
product_name,
list_price
FROM
udfProductInYear(2018);
我正在使用 SQL Server 2017,版本 14.0.2002.14
(开发版(64 位))
我正在尝试创建一个函数,用户可以在其中传递多个值来过滤查询。
我通常可以使用只需要一个参数的函数来完成,使用下面的模板:
CREATE FUNCTION func_1
(
@StartDate date,
@EndDate date
)
RETURNS TABLE AS
RETURN
(
SELECT * FROM table_name
WHERE table_name.Date BETWEEN @StartDate and @EndDate
)
用户可以通过以下操作return过滤结果:
SELECT * FROM func_1('20190101', '20191231')
当尝试通过传入多个值来 return 结果时,此查询在 SQL 服务器上执行时有效:
-- Declare a TABLE variable to be used as a filter
DECLARE @Product TABLE
(
Products varchar(10)
)
INSERT INTO @Product VALUES('value_1', 'value_2')
-- Return filtered results from query
SELECT Date, Product, Quantity
FROM Table_Name
WHERE Table_Name.Product IS IN (SELECT Products FROM @Product)
但是,我想将它创建为一个函数,SQL 服务器不喜欢...
CREATE FUNCTION func_2
(
@StartDate date,
@EndDate date,
@Product TABLE
(
Product varchar(10)
)
INSERT INTO @Product VALUES()
)
RETURNS TABLE AS
RETURN
(
SELECT Date, Product, Quantity
FROM Table_Name
WHERE Date BETWEEN @StartDate AND @EndDate
AND Table_Name.Product IS IN (SELECT Products FROM @Product)
)
用户应调用此查询并获得 return 过滤结果:
SELECT * FROM func_2('20190101', '20191231', ('value_1', 'value_2', 'value_3'))
编辑:也向 func_2 添加了日期参数,即该函数的预期用途是根据 1 个以上的参数进行过滤
我做过类似的事情。您必须创建一个 table 类型,它将是一个字符串列表。例如:
CREATE TYPE FilterType AS TABLE (MyFilter VARCHAR(10))
然后,您可以在存储过程中指定此参数(函数错误不可用我认为它无论如何都会用存储过程执行您想要的操作)。
CREATE PROCEDURE MyProc (@filters FilterType READONLY, ...)
进入程序后,您可以将其用作 table
SELECT * FROM YourTable t join @filters f on f.MyFilter = t.Column
这样做的好处是您可以根据需要定义 TYPE 并根据需要向其添加任意数量的参数。
以下link中的内容与您想要实现的功能相同,但仅针对一个参数。
sql-server-user-defined-functions
CREATE FUNCTION udfProductInYear (
@model_year INT
)
RETURNS TABLE
AS
RETURN
SELECT
product_name,
model_year,
list_price
FROM
production.products
WHERE
model_year = @model_year;
访问您的函数时,请使用以下内容:
SELECT
product_name,
list_price
FROM
udfProductInYear(2018);