动态SQL:使用在字符串之外的字符串中声明的变量

时间:2015-10-02 13:36:14

标签: sql sql-server stored-procedures sql-server-2012

我有一个存储过程,应该计算一个人的年龄。

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

alter PROCEDURE [dbo].[ageTest] 
(
 @curDate date 
 )
AS
BEGIN
    SET NOCOUNT ON;
declare @sql nvarchar(max)
declare @params nvarchar (1000) 

declare @age date

set @params = N' @curDate date , @age date output'
set @sql = '
declare @dif float 
declare @ageRound int
declare @theAge varchar (100)
set @age = ''19890406''
set @theAge =(select (datediff (mm, @age , getdate()))) 
set @dif = @theAge % 12
set @ageRound = cast (@theAge as float)/12 
select @ageRound as Years, @dif as months  
'

set @sql = replace (@sql, '19890406', @curDate)
execute sp_executesql @sql, @params, @curDate, @age output

end

execute [dbo].[ageTest] '19511214'

我想要获得的是两列:

Years     Months
63         10

现在它看起来像这样: enter image description here

问题在于循环。我应该从@sql删除选择并将其放在外面,然后我有声明问题。想法?

编辑:不重复

1 个答案:

答案 0 :(得分:3)

如果你真的只是一个初学者。

首先,您应始终在程序中使用TRY...CATCH阻止。

在这里快速重写您在代码中所做的事情:

-- =============================================
-- Procedure Name   : dbo.ageTest
-- Usage Example    : EXECUTE [dbo].[ageTest] '19511214';
-- =============================================
ALTER PROCEDURE [dbo].[ageTest]
(
    @curDate DATE
)
AS
BEGIN
    SET NOCOUNT ON;
    BEGIN TRY
        SELECT DATEDIFF(MM, @curDate, CURRENT_TIMESTAMP) / 12 AS Years
            , DATEDIFF(MM, @curDate, CURRENT_TIMESTAMP) % 12 AS Months;
    END TRY
    BEGIN CATCH
        SELECT ERROR_NUMBER(), ERROR_MESSAGE();
    END CATCH
END

它显示了如何在SP中使用参数。