SQL Server:如何通过动态SQL生成序列号

时间:2018-08-05 17:49:33

标签: sql-server

VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT
  1. 现在告诉我如何用上述SQL编写或形成动态SQL,在调用存储过程时将表名传递给存储过程吗?

  2. 如何将create procedure test (@TABLE_NAME varchar(20)) as declare @lastval varchar(10) set @lastval = right('000000000' + convert(varchar(10), (select IsNull(max(Serialno), 0) + 1 from @TABLE_NAME)), 10) return @lastval end 的值返回到其调用环境?

  3. 如何从另一个将存储返回值的存储过程中调用存储过程测试?

为我提供示例代码。

1 个答案:

答案 0 :(得分:0)

通常,最好使用IDENTITYSEQUENCE来分配序列号。可以将零填充字符串或其他格式要求作为基于基础序列整数的计算列添加到表中,或以应用程序代码的格式设置。但是,IDENTITYSEQUENCE可能都存在间隙,例如由于回滚或SQL Server服务重新启动。

如果企业需要连续的序列值序列,则可以维护表中最后分配的值并进行事务性分配。以下是使用OUTPUT参数返回值的示例。尽管您问题中的proc为此使用了存储的proc RETURN值,但该值仅应用于指示成功或失败,而不是返回数据。

CREATE TABLE dbo.TableSerialNumber(
      TableName sysname NOT NULL
        CONSTRAINT PK_SerialNumber PRIMARY KEY
    , SerialNumber int NOT NULL
    , FormatString nvarchar(20) NULL
);
GO
INSERT INTO dbo.TableSerialNumber VALUES('Invoice', 0, '0000000000');
INSERT INTO dbo.TableSerialNumber VALUES('PurchaseOrder', 0, '0000000000');
GO

CREATE PROC dbo.GetNextSerialNumberForTable
      @TableName sysname
    , @FormattedSerialNumber varchar(10) OUTPUT
AS
SET NOCOUNT ON;
DECLARE
      @SerialNumber int
    , @FormatString nvarchar(20);

UPDATE dbo.TableSerialNumber
SET
      @SerialNumber = SerialNumber += 1
    , @FormatString = FormatString
WHERE TableName = @TableName;
IF @@ROWCOUNT = 0
    RAISERROR('Table %s does not exist in dbo.TableSerialNumber', 16, 1, @TableName);
SET @FormattedSerialNumber = CAST(FORMAT(@SerialNumber, @FormatString) AS varchar(10));
GO

--example usage
CREATE PROC dbo.InsertInvoice
    @InvoiceData int
AS
SET XACT_ABORT ON;
DECLARE @InvoiceNumber varchar(10);
BEGIN TRY
    BEGIN TRAN;
    EXECUTE dbo.GetNextSerialNumberForTable
          @TableName = N'Invoice'
        , @FormattedSerialNumber = @InvoiceNumber OUTPUT;
    INSERT INTO dbo.Invoice (InvoiceID, InvoiceData)
        VALUES(@InvoiceNumber, @InvoiceData);
    SELECT @InvoiceNumber AS InvoiceNumber;
    COMMIT;
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0 ROLLBACK;
    THROW;
END CATCH;
GO