在SQL Server中创建和执行函数

时间:2016-11-21 11:53:14

标签: sql-server tsql sql-server-2012 sql-function

我有四张桌子:

  1. dbo.Projects
  2. dbo.Locations(id,位置名称)
  3. dbo.Purpose(id,Purposename)
  4. dbo.Types(id,typname)
  5. 我有一个搜索条件,此条件填充了数据库表格中的数据:locationspurposetypes

    我想创建一个函数,该函数返回表,其中projects的搜索结果依赖于其他表。我已经创建了一个,但它不能满足我的需求:

     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的新手,所以感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

我会选择:

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

如果您只想返回符合条件所有条件的项目,并且输入参数中的空字符串被视为通配符:

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值。

如果要返回满足输入参数中任何条件的项目(并且当至少一个输入参数包含值时不将空输入参数视为通配符),则可以更改AND子句中的WHEREOR s,并且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'
这里需要

NULL不需要的输入参数,因为在任何输入参数中调用带有空字符串的函数会导致返回所有记录:

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

答案 1 :(得分:0)

加入对我来说不合适。您没有完全指定您的架构,所以我猜测,但是使用这些连接的情况是非常不寻常的。

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

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('',' ','');

很抱歉,如果我错过了问题中的某些内容或评论显示这不是答案......