【问题标题】:SQL User defined function, can't find dbo or user-defined functionSQL 用户定义函数,找不到 dbo 或用户定义函数
【发布时间】:2012-07-25 00:59:10
【问题描述】:

我使用这个查询在我的数据库中创建了一个函数:

CREATE FUNCTION dbo.fnSplit(
    @sInputList VARCHAR(MAX) -- List of delimited items
  , @sDelimiter VARCHAR(MAX) = ',' -- delimiter that separates items
) RETURNS @List TABLE (item VARCHAR(MAX))

BEGIN
DECLARE @sItem VARCHAR(MAX)
WHILE CHARINDEX(@sDelimiter,@sInputList,0) <> 0
 BEGIN
 SELECT
  @sItem=RTRIM(LTRIM(SUBSTRING(@sInputList,1,CHARINDEX(@sDelimiter,@sInputList,0)-1))),
  @sInputList=RTRIM(LTRIM(SUBSTRING(@sInputList,CHARINDEX(@sDelimiter,@sInputList,0)+LEN(@sDelimiter),LEN(@sInputList))))

 IF LEN(@sItem) > 0
  INSERT INTO @List SELECT @sItem
 END

IF LEN(@sInputList) > 0
 INSERT INTO @List SELECT @sInputList -- Put the last item in
RETURN
END
GO

SQL Server 返回:Command(s) completed successfully.

然后我尝试运行这个查询:

SELECT * FROM maj_Posts a
WHERE FeedID = (SELECT dbo.fnSplit(b.FeedIDs) FROM maj_Magazines b WHERE OwnerID = 1)
ORDER BY countOfComments DESC 

返回错误:Msg 4121, Level 16, State 1, Line 1 Cannot find either column "dbo" or the user-defined function or aggregate "dbo.fnSplit", or the name is ambiguous.

注意b.FeedIDs是一个包含逗号分隔数字的字符串,像这样:1,2,4

我想从maj_Posts 获取行,它们的a.FeedIDb.FeedIDs 中的数字之一...(例如,如果b.FeedIDs1,2,4,我需要来自 maj_Posts 的行,它们的 FeedID 是 1 或 2 或 4。)

有什么问题?

【问题讨论】:

  • 您已经创建了表值函数,但您正在使用它,就好像它是标量函数一样。
  • 我没听懂你说的。你能解释一下吗?
  • 这类函数属于FROM子句。
  • 我是 SQL Server 用户定义函数的新手,不知道哪种函数适合我。你能帮我修复这段代码吗?

标签: sql sql-server sql-server-2005 select user-defined-functions


【解决方案1】:

也许你的意思是:

SELECT * FROM maj_Posts a
LEFT OUTER JOIN dbo.maj_Magazines b
ON 1 = 1 AND b.OwnerID = 1
OUTER APPLY dbo.fnSplit(b.FeedIDs, ',') AS s
WHERE a.FeedID = s.item
ORDER BY countOfComments DESC;

或者

SELECT * FROM maj_Posts a
WHERE FeedID IN 
(
  SELECT item FROM maj_Magazines AS b
  CROSS APPLY dbo.fnSplit(b.FeedIDs, ',') 
  WHERE b.OwnerID = 1
)
ORDER BY countOfComments DESC;

【讨论】:

  • 谢谢!两者都有效。但似乎fnSplit 中的可选参数不起作用,我将您的代码更改为dbo.fnSplit(b.FeedIDs,',')。你能解释一下为什么可选参数不起作用吗?
  • 对不起,我错过了分隔符。我不能告诉你为什么可选参数在用户定义的函数中不起作用,我只知道它们不起作用。您总是需要传递所有参数(指定默认值的唯一原因是记录您期望的典型值)。
  • 谢谢。你的第二个 SQL 查询对我来说似乎更容易理解!
  • 我不明白CROSS APPLYOUTER APPLY是干什么的?
【解决方案2】:
USE [oberoi]
GO
/****** Object:  StoredProcedure [dbo].[sp_AssetReport]    Script Date: 03/23/2013 12:27:47 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_AssetReport]
AS


BEGIN
SELECT     distinct am.assetid,am.computerName,
 ao.os_name,ao.user_name,ao.reg_code, ao.reg_org, ao.reg_to,
 ao.localization,  ao.product_key,
-- an.ip_address,

   amem.physical_mem,amem.virtual_mem,(Select top 1 ip_address from Asset_Network where assetId=am.assetid) as ip_address,ap.processor_name,ap.speed,  ap.manufacturer,
   api.serial_number,api.product_name, api.product_manufacturer,am.TagNo,am.PONo,dbo.capacity_checkn(apd.capacity) as capacity,am.Location,am.AssetOwner,am.CompanyCode,am.PurchaseDate,am.AssetCategory,am.Remarks
FROM                  Asset_mst As am INNER JOIN
                     -- Asset_Network AS an ON am.assetId = an.assetId INNER JOIN
                      --Asset_Inventory As AI on an.assetId=AI.assetId INNER JOIN
                      Asset_OperatingSystem AS ao on am.assetId=ao.assetId JOIN
                      Asset_Memory AS amem ON ao.assetId = amem.assetId INNER JOIN
                      Asset_Processor AS ap ON amem.assetId = ap.assetId INNER JOIN
                      Asset_ProductInfo AS api ON ap.assetId = api.assetid INNER JOIN
                      Asset_PhysicalDrive AS apd ON am.assetId = apd.assetid 


where CONVERT(datetime,CONVERT(char(12),Am.createdatetime )) = CONVERT(datetime,CONVERT(char(12),ao.inventory_date )) 
--And CONVERT(datetime,CONVERT(char(12),an.inventory_date )) = CONVERT(datetime,CONVERT(char(12),AI.inventoryDate ))
--And CONVERT(datetime,CONVERT(char(12),an.inventory_date )) = CONVERT(datetime,CONVERT(char(12),ao.inventory_date )) 
And 
CONVERT(datetime,CONVERT(char(12),Ao.inventory_date )) = CONVERT(datetime,CONVERT(char(12),amem.inventory_date )) 
And CONVERT(datetime,CONVERT(char(12),amem.inventory_date )) = CONVERT(datetime,CONVERT(char(12),ap.inventory_date ))
And CONVERT(datetime,CONVERT(char(12),ap.inventory_date )) = CONVERT(datetime,CONVERT(char(12),api.inventory_date ))
And CONVERT(datetime,CONVERT(char(12),api.inventory_date )) = CONVERT(datetime,CONVERT(char(12),apd.inventory_date ))
and am.Isdelete=0

enter code here

End

【讨论】:

    猜你喜欢
    • 2017-07-22
    • 1970-01-01
    • 1970-01-01
    • 2015-05-26
    • 2020-12-07
    • 2014-01-06
    • 2019-08-01
    • 2011-01-06
    • 2019-02-09
    相关资源
    最近更新 更多