在 SQL 服务器中创建并执行函数

Create and execute function in SQL Server

我有四个table:

  1. dbo.Projects
  2. dbo.Locations (id, 地点名称)
  3. dbo.Purpose (id, Purposename)
  4. dbo.Types (id, typname)

我有一个搜索条件,这个条件填充了来自数据库 tables 的数据:locationspurposetypes

我想创建一个 returns table 的函数,其中 projects 的搜索结果依赖于其他 table。我创建了一个,但它不能满足我的需要:

 ALTER FUNCTION SearchProjects
 (
     @location nvarchar(50),
     @purpose nvarchar(50),
     @type nvarchar(50)
 )
 RETURNS TABLE
 AS
 RETURN
(
      SELECT dbo.Projects.ProjectName, dbo.Projects.Areas,           
             dbo.Projects.PaymentSystem, dbo.Projects.ReceivedDate,    
             dbo.Projects.PropertyClassification, 
             dbo.Projects.ProjectImage
      FROM dbo.Locations INNER JOIN
      INNER JOIN dbo.Projects ON dbo.Locations.ID = dbo.Projects.ID      
      INNER JOIN dbo.Purpose ON dbo.Locations.ID = dbo.Purpose.ID 
      INNER JOIN dbo.Types ON dbo.Locations.ID = dbo.Types.ID
      WHERE (Projects.ProjectName like N'%'+ @location +'%' 
         and Purpose.PurposeName = N'%'+ @purpose +'%' 
         and Types.TypeName like N'%'+ @type     +'%')
 )
 GO
 SELECT * FROM dbo.SearchProjects('',' ','');

我是 SQL SERVER 的新手,非常感谢您的帮助。

我觉得这些连接不对。你没有完全指定你的模式,所以我猜,但使用这些连接的情况是很不寻常的。

在此示例中,我更改了为每个连接指定的列,但我猜测这些列在您的表中可能被命名为什么。

Alter FUNCTION SearchProjects (
    @location nvarchar(50),
    @purpose nvarchar(50),
    @type nvarchar(50))
 RETURNS TABLE
 AS
 RETURN
(
 SELECT p.ProjectName, 
     p.Areas, 
     p.PaymentSystem, 
     p.ReceivedDate,    
     p.PropertyClassification, 
     p.ProjectImage
  FROM dbo.Projects As p 
  LEFT JOIN dbo.Locations As l ON p.LocationID = l.ID      
  LEFT JOIN dbo.Purpose ON p.PurposeID = Purpose.ID 
  LEFT JOIN dbo.Types As t ON p.TypeID = t.ID
  WHERE (l.LocationName like N'%'+ @location +'%' 
         OR Purpose.PurposeName = N'%'+ @purpose +'%' 
         OR t.TypeName like N'%'+ @type     +'%')
 )
 GO

 SELECT * FROM dbo.SearchProjects('',' ','');

抱歉,如果我在问题或评论中遗漏了表明这不是答案的内容...

我会选择:

ALTER FUNCTION SearchProjects (
    @location NVARCHAR(50),
    @purpose NVARCHAR(50),
    @type NVARCHAR(50))
RETURNS TABLE
AS
RETURN
(
    SELECT  p.ProjectName, 
            p.Areas, 
            p.PaymentSystem, 
            p.ReceivedDate,    
            p.PropertyClassification, 
            p.ProjectImage,
            l.LocationName,
            pur.PurposeName,
            t.TypeName
    FROM dbo.Projects AS p 
    LEFT JOIN dbo.Locations AS l ON p.LocationID = l.ID      
    LEFT JOIN dbo.Purposes pur ON p.PurposeID = pur.ID 
    LEFT JOIN dbo.[Types] AS t ON p.TypeID = t.ID
    WHERE UPPER(ISNULL(l.LocationName,N'')) LIKE N'%' + UPPER(@location) + '%'
    AND UPPER(ISNULL(pur.PurposeName,N'')) LIKE N'%' + UPPER(@purpose) + '%'
    AND UPPER(ISNULL(t.TypeName,N'')) LIKE N'%' + UPPER(@type) + '%'
     )
GO

如果您只想 return 满足 所有 条件且输入参数中的空字符串被视为通配符的项目:

SELECT * FROM dbo.SearchProjects('','',''); -- Returns all records

SELECT * FROM dbo.SearchProjects('north','',''); -- Returns all records with LocationName containing 'north'
SELECT * FROM dbo.SearchProjects('','research',''); -- Returns all records with PurposeName containing 'research'
SELECT * FROM dbo.SearchProjects('','','closed'); -- Returns all records with TypeName containing 'closed'

SELECT * FROM dbo.SearchProjects('north','research',''); -- Returns all records with LocationName containing 'north' and PurposeName containing 'research'

这还会在将输入参数值与表中的字段值进行比较时消除任何大小写敏感性。我仍然会使用 LEFT JOIN 而不是 INNER JOIN 以防某些项目记录可能有错误的 LocationID、PurposeID 或 TypeID 值。

如果您想 return 满足输入参数中 任何 条件的项目(并且当至少有一个输入时,不将空输入参数视为通配符参数包含一个值),您可以将 WHERE 子句中的 ANDs 更改为 ORs 并为您不希望指定的任何输入参数传递 NULL价值:

ALTER FUNCTION SearchProjects (
    @location NVARCHAR(50),
    @purpose NVARCHAR(50),
    @type NVARCHAR(50))
RETURNS TABLE
AS
RETURN
(
    SELECT  p.ProjectName, 
            p.Areas, 
            p.PaymentSystem, 
            p.ReceivedDate,    
            p.PropertyClassification, 
            p.ProjectImage,
            l.LocationName,
            pur.PurposeName,
            t.TypeName
    FROM dbo.Projects AS p 
    LEFT JOIN dbo.Locations AS l ON p.LocationID = l.ID      
    LEFT JOIN dbo.Purposes pur ON p.PurposeID = pur.ID 
    LEFT JOIN dbo.[Types] AS t ON p.TypeID = t.ID
    WHERE UPPER(ISNULL(l.LocationName,N'')) LIKE N'%' + UPPER(@location) + '%'
    OR UPPER(ISNULL(pur.PurposeName,N'')) LIKE N'%' + UPPER(@purpose) + '%'
    OR UPPER(ISNULL(t.TypeName,N'')) LIKE N'%' + UPPER(@type) + '%'
     )
GO


SELECT * FROM dbo.SearchProjects('','',''); -- Returns all records

SELECT * FROM dbo.SearchProjects('north',NULL,NULL); -- Returns all records with LocationName containing 'north'
SELECT * FROM dbo.SearchProjects(NULL,'research',NULL); -- Returns all records with PurposeName containing 'research'
SELECT * FROM dbo.SearchProjects(NULL,NULL,'closed'); -- Returns all records with TypeName containing 'closed'

SELECT * FROM dbo.SearchProjects('north','research',NULL); -- Returns all records with LocationName containing 'north' or PurposeName containing 'research'

NULLing 不需要的输入参数在这里是必要的,因为在任何输入参数中使用空字符串调用函数将导致所有记录被 returned:

SELECT * FROM dbo.SearchProjects('north','','');
SELECT * FROM dbo.SearchProjects('north','research','');
SELECT * FROM dbo.SearchProjects('north','','closed');