视图中的子查询不能正常工作

时间:2015-06-10 13:23:15

标签: sql-server

嘿我正在创建在FastReport(ReportingSoftware)中使用的视图,我在其中有一个标量值函数形式的子查询,将属性的完整地址拉到一起,虽然它带回了错误子查询返回超过1个值,我不知道为什么,我过去使用类似的东西似乎无法找出问题。

这是我的观看代码

SELECT  TOP (100) PERCENT dbo.PropertyMaster.PropertyID, 
        dbo.Lookup_PropertyManager.Description, dbo.Lookup_PropertyManager.Email, 
        dbo.GetFullAddress(dbo.PropertyMaster.PropertyID) AS FullAddress, 
        dbo.Tenants.TenantID, dbo.Tenants.LeaseID, 
        dbo.Tenants.TenantForeName + ' ' + dbo.Tenants.TenantSurname AS FullName, 
        dbo.PropertyMaster.SPMReference, 
        CONVERT(varchar, dbo.PropertyLease.StartDate,101) AS StartDate, 
        CONVERT(varchar, dbo.PropertyLease.DateSigned, 101) AS DateSigned
FROM  dbo.PropertyLease 
      RIGHT OUTER JOIN dbo.PropertyMaster 
             ON dbo.PropertyLease.PropertyID = dbo.PropertyMaster.PropertyID 
      LEFT OUTER JOIN dbo.Tenants 
             ON dbo.PropertyMaster.PropertyID = dbo.Tenants.PropertyID 
      LEFT OUTER JOIN dbo.Lookup_PropertyManager 
    ON dbo.PropertyMaster.PropertyManagerID = dbo.Lookup_PropertyManager.PropertyManagerID
ORDER BY dbo.PropertyMaster.PropertyID

这是我的标量值函数

ALTER FUNCTION [dbo].[GetFullAddress] 
    -- Add the parameters for the function here
    (@PropertyID as integer )
RETURNS varchar(250) 
AS
BEGIN
DECLARE @AddressLine as varchar(40)
DECLARE @FullAddress as varchar(250)
SET @FullAddress = (SELECT LTRIM(ISNULL(TenantForeName + ' ', ' ') + TenantSurname) AS FullName FROM Tenants  WHERE PropertyID = @PropertyID) + CHAR(10)


SET @AddressLine = (SELECT ISNULL(AddressLine1, '') FROM PropertyMaster WHERE PropertyID = @PropertyID)
SET @FullAddress = @FullAddress + @AddressLine + CHAR(10)
        SET @AddressLine = (SELECT  ISNULL(AddressLine2, '') FROM PropertyMaster WHERE PropertyID = @PropertyID)
IF @AddressLine <> ''
    BEGIN
        SET @FullAddress = @FullAddress + @AddressLine + CHAR(10)
    END
        SET @AddressLine = (SELECT  ISNULL(AddressLine3, '') FROM PropertyMaster WHERE PropertyID = @PropertyID)
IF @AddressLine <> ''
    BEGIN
        SET @FullAddress = @FullAddress + @AddressLine + CHAR(10)
    END
SET @AddressLine = (SELECT ISNULL(Town, '' ) FROM PropertyMaster WHERE PropertyID = @PropertyID)
IF @AddressLine <> ''
    BEGIN
        SET @FullAddress = @FullAddress + @AddressLine + CHAR(10)
    END
SET @AddressLine = (SELECT ISNULL(PostCode, '') FROM PropertyMaster WHERE PropertyID = @PropertyID)
SET @FullAddress = @FullAddress + @AddressLine

RETURN @FullAddress
END

2 个答案:

答案 0 :(得分:3)

问题很可能是这一行

SET @FullAddress = (SELECT LTRIM(ISNULL(TenantForeName + ' ', ' ') + TenantSurname) AS FullName FROM Tenants  WHERE PropertyID = @PropertyID) + CHAR(10)

您可以通过添加Top 1

将其更改为获得第一个租户
SET @FullAddress = (SELECT TOP 1 LTRIM(ISNULL(TenantForeName + ' ', ' ') + TenantSurname) AS FullName FROM Tenants  WHERE PropertyID = @PropertyID) + CHAR(10)

或者您可以将所有租户连接在一起。

SELECT @FullAddress = COALESCE(@FullAddress, '') 
       + LTRIM(ISNULL(TenantForeName + ' ', ' ') + TenantSurname) AS FullName 
FROM   Tenants  
WHERE  PropertyID = @PropertyID) + CHAR(10)

P.S。如果这是问题。您的视图最像是返回重复的行,因为您还要加入租户表。如果您的视图中的每个租户都需要一行,那么您可能希望将tenantid传递给该函数,并将其作为where子句添加到查询中以获取租户名称。

答案 1 :(得分:1)

这不是问题的答案 我只是在这里发帖,因为几乎不可能阅读评论中发布的代码。

除了user1221684在他/她answer中写的内容, 函数的其余部分可以这样写:

SELECT @FullAddress = @FullAddress + CHAR(10) +
       ISNULL(AddressLine1 + CHAR(10), '')  +
       ISNULL(AddressLine2 + CHAR(10), '') +
       ISNULL(AddressLine3 + CHAR(10), '') +
       ISNULL(Town + CHAR(10), '' ) + 
       ISNULL(PostCode, '')
FROM PropertyMaster WHERE PropertyID = @PropertyID

<强>解释
实际上不需要从同一个表中选择不同的列 在多个查询中。

在sql server中,当您将字符串(在本例中为char(10))连接到空值时,结果为null。如果ISNULL(AddressLine1 + CHAR(10), '')为空,那么AddressLine1将返回一个空字符串。