【问题标题】:Is it an SQL SERVER bug?它是 SQL SERVER 错误吗?
【发布时间】:2014-11-11 15:52:43
【问题描述】:

我似乎无法弄清楚这个 SQL 标量函数发生了什么。我想知道这是否是我遇到的某种错误,因为 select 语句在函数中返回 NULL,而它在函数外工作得很好,或者当 DESC 子句被省略时。

ALTER FUNCTION [dbo].[getInvoiceNumbers]
(

@vatable bit

)
RETURNS nvarchar(20)
AS
BEGIN

DECLARE @latestNonVATInvNumber nvarchar(20), 
        @latestVATInvNumber nvarchar(20), @invoiceNumber nvarchar(20)

if @vatable = 'true'
    begin    
        select TOP 1 @latestVATInvNumber = invoiceNumber from dbo.Invoices where vatable = 'true' ORDER BY invoiceID desc 

        /* remove 'B' from invoice number and convert to int from string */

        set @latestVATInvNumber = cast(substring(@latestVATInvNumber,2,len(@latestVATInvNumber)) as int) + 1

        /* Add 'B' to receipt number with leading zeros so that it is 7 digits including 'B' */

        set @latestVATInvNumber  = 'B' + RIGHT('000000'+ CAST(@latestVATInvNumber AS VARCHAR(6)),6)

        set @invoiceNumber = @latestVATInvNumber
    end
else
    begin

        select TOP 1 @latestNonVATInvNumber = invoiceNumber from dbo.Invoices where vatable = (select cast ('False' as bit)) ORDER BY invoiceID desc


        /* Invoice Number is numeric (non VAT) hence only incrementing it by 1 */

        set @latestNonVATInvNumber = cast(cast(@latestNonVATInvNumber as int) + 1 as nvarchar(10))                                                                                                                                                                                                                                                                                                       

        set @invoiceNumber = @latestNonVATInvNumber
    end

-- Return the result of the function
RETURN @invoiceNumber 

END

给出NULL的部分是这段代码:

select TOP 1 @latestNonVATInvNumber = invoiceNumber from dbo.Invoices where vatable = (select cast ('False' as bit)) ORDER BY invoiceID desc

 select TOP 1 @latestVATInvNumber = invoiceNumber from dbo.Invoices where vatable = 'true' ORDER BY invoiceID desc 

如果我删除了“DESC”,那么它会给我来自数据库的结果,或者即使插入了“ASC”,但如果在表。

有什么建议吗?

【问题讨论】:

  • vatable 列的数据类型是什么?
  • 'vatable' 列的数据类型是 BIT

标签: sql-server tsql select stored-functions


【解决方案1】:

建议一(不正确):

第一次查询表时,使用以下过滤器:

where vatable = 'true'

第二次查询时,使用以下内容:

(select cast ('False' as bit))

通过删除 CAST 并使用 where vatable = 'false' 将它们更改为相互匹配。

建议二(答案):

AND InvoiceNumber IS NOT NULL 添加到您的条件中

【讨论】:

  • 两者都试过了,但都没有用,这就是为什么我尝试 CAST 来思考 BIT 列是否在查询中搞砸了。单独运行或单独运行时,这两个查询都运行良好。
  • 尝试将AND InvoiceNumber IS NOT NULL 添加到您的条件中并检查是否/返回了多少行
  • AHiggins 你已经找到了,伙计,谢谢。添加此子句起到了作用。您能解释一下为什么 InvoiceNumber 列不能包含 NULL 且不能为空吗?
  • select TOP 1 @latestVATInvNumber = invoiceNumber from dbo.Invoices where vatable = 'true' AND invoiceNumber IS NOT NULL ORDER BY invoiceID desc
  • 所以您是说 InvoiceNumber 列被定义为不包含 NULL 值? SELECT COUNT(*) FROM Invoices WHERE InvoiceNumber IS NULL 返回零?
【解决方案2】:

如果您返回超过 1 行,则使用 TOP 1,然后更改返回结果的顺序可能会更改返回给您的 @latestNonVATInvNumber 变量的输出。

我的建议是测试前 1 部分并尝试选择 COUNT(*) 以查看返回的行数。

例如

select COUNT(*) from dbo.Invoices where vatable = (select cast ('False' as bit)) ORDER BY invoiceID desc

然后你可以用类似的东西测试返回什么数据

select * from dbo.Invoices where vatable = (select cast ('False' as bit)) ORDER BY invoiceID desc

也许那样会更清楚为什么会出现 NULL。

【讨论】:

  • 据我所知,TOP 1 通常只返回 1 行。但是通过将选择修改为此“select COUNT() from dbo.Invoices where vatable = (select cast ('False' as bit)) GROUP BY invoiceID”来尝试您的建议。正如预期的那样,count() 只返回 1 行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 2012-03-08
  • 2015-04-24
相关资源
最近更新 更多