储存程序

时间:2018-07-07 08:55:29

标签: c# sql sql-server visual-studio stored-procedures

您能帮帮我吗?我有这个字符串插入到名为tblApplication

的表中
 insert into tblApplication (ApplicationID,ControlNo,Name)
 values 
 (@AppID,Name);

我希望如果我将其插入tblApplication,存储过程将为插入的应用程序生成一个控制号。

控制编号的格式类似于 18-0001 年,并且根据特定年份的申请数量生成控制编号

select Concat( ( YEAR( GETDATE() ) % 100 ),'-', ( select count(AppicationID) + 
1 from tblApplication where year(TransactionDate) = year(getDate()) + 1 ) )

“我的存储过程”就是这样,并基于我对Google中存储过程的理解,但我对此不太确定

CREATE PROCEDURE GenerateControlNumberForInsertedApplication
    @ApplicationID Varchar(MAX)
AS
BEGIN
    SET NOCOUNT ON;

    UPDATE tblApplication set ControlNo = @ApplicationID
END

2 个答案:

答案 0 :(得分:2)

根据我的想法,您的申请表如下

表:tblApplication Colmuns:ApplicationID,ControlNo,Name,TransactionDate

因此,当您插入时,仅插入ApplicationId,Name。 (我希望应用程序ID是唯一的)

  1. 您的插入语句应如下所示

     INSERT INTO tblApplication (ApplicationId , Name) Values (@AppID,@Name)
    
  2. 创建触发器

      CREATE TRIGGER trgAfterInsert on tblApplication
      FOR INSERT
      BEGIN
      DECLARE @ControlNumber NVARCHAR(50) 
      DECLARE @AppId INT
      select @ControlNumber = Concat( ( YEAR( GETDATE() ) % 100 ),'-', ( select 
      count(AppicationID) + 
      1 from tblApplication where year(TransactionDate) = year(getDate()) + 1 ) )
    
      Select @AppId = ApplicationId from inserted
    
      Update tblApplication SET ControlNumber = @ControlNumber where ApplicationId 
     = @AppId
    

    END

答案 1 :(得分:0)

我只想提及另一种方法。由于您要计算ApplicationID的数量,因此在结果中加1。我有一些对您的情况有用的方法。

  1. 使用Scalar Function
  2. 生成控制编号
  3. 使用Sequence
  4. 生成控制编号
  5. 在tblApplication中使用Computed Column
  6. 在tblApplication中使用IDENTITY
  7. 使用具有生成的控件编号的视图。

有关更多说明,如果您使用标量函数来生成控制编号,那么您将具有在比存储过程更大的灵活性下使用通用函数的优势。此方法可以与对行进行计数并将结果加1的相同方法一起使用,也可以添加标识列以使事情由SQL Server自动化和控制。另一种方法是使用标量函数+标识列添加计算列,这将为您提供保存控制编号的列,而无需进行转换和执行额外的步骤。

因此,标量函数是类似于YEAR(),COUNT()。etc等函数的函数。您只需要设置它,它将在您使用它的任何地方为您提供输出。 (有点像Java C#中的方法和Javascript中的函数,但有SQL限制)。

要创建标量函数,可以执行以下操作:

CREATE FUNCTION FN_ControlNumber()
RETURNS VARCHAR(100)
AS
BEGIN

    DECLARE
        @Result         VARCHAR(100)
    ,   @ApplicationId  INT 

SET @ApplicationId = (SELECT COUNT(ApplicationId) + 1 FROM tblApplication WHERE YEAR(TransactionDate) =  YEAR(GETDATE()) + 1)

SET 
    @Result = CAST(YEAR(GETDATE()) % 100  AS VARCHAR(2) ) + '-' + CAST(@ApplicationId + 1 AS VARCHAR(97))

    RETURN @Result

END

然后称呼它:

SELECT dbo.FN_ControlNumber()

结果将是新的控制号,因此您可以从C#(使用executeScalar),存储过程,触发器,视图或要生成新控制号的任何位置调用它。

如果您想要其他方法,可以使用如下视图:

CREATE VIEW tblApplication_ControlNumber
AS
SELECT 
    CAST(YEAR(GETDATE()) % 100  AS VARCHAR(2) ) + '-' + CAST(ControlNumber + 1 AS VARCHAR(97)) AS ControlNumber
FROM (
SELECT 
    COUNT(ApplicationId) + 1 AS ControlNumber 
FROM 
        tblApplication 
WHERE 
    YEAR(TransactionDate) =  YEAR(GETDATE()) + 1 
) D 

与函数输出类似,但是您需要这样调用它:

SELECT ControlNumber FROM tblApplication_ControlNumber

如果您需要全局使用顺序编号(与其他表一起使用)或什至只与一个表一起使用,则在这里没有太大关系。想法是,序列类似于IDENTITY,但与表并不紧密。因此,您可以在一张或多张桌子上使用它。如果您拥有创建一个特权的权限,那么我建议您使用它,是否比确定身份更有效。

我的建议是添加一个IDENTITY列以使DBMS控制顺序并将其设置为PRIMARY KEY,然后使用标量函数以IDENTITY列作为输入来生成控制号并将其用于计算列中。这将为每个插入自动计算。因此,无需存储过程,就不需要触发器。如果以某种方式更改了控制编号格式,则只需从函数中更改格式,计算列内所有生成的控制编号将自动更新。

如果您愿意接受我的建议,您的功能将如下所示:

CREATE FUNCTION FN_GenerateSequence
(
    @ID     INT
)
RETURNS VARCHAR(100)
AS
BEGIN

    DECLARE
        @Result         VARCHAR(100)


SET 
    @Result = CAST(YEAR(GETDATE()) % 100  AS VARCHAR(2) ) + '-' + CAST(@ApplicationId AS VARCHAR(97))


    RETURN @Result

END

然后,您可以使用INT这样的任何列调用它:

SELECT dbo.FN_GenerateSequence(ID)

如果要在计算列中使用它,只需使用它:

dbo.FN_GenerateSequence(ComputedColumnName)

这是一些有用的方法,我刚刚提到它们是为了给您另一种观点,并且可能会有所帮助。