如何在Sql server中创建表的存储过程,其中表的名称将按年份更改,例如Order2019

如何在Sql server中创建表的存储过程,其中表的名称将按年份更改,例如Order2019,sql,sql-server,stored-procedures,Sql,Sql Server,Stored Procedures,我正在用C#.Net制作一个桌面应用程序,并想在Sql server中制作一个存储过程。它应该首先检查表是否存在,如果存在,它应该在表中插入值,否则创建表,表名将从winForm中动态获取,就像2019年的表应该是2019年的表,接下来它应该创建table2020,依此类推 CREATE PROCEDURE SaveOrderByYear(@tableName varchar(50),@SaleOrderID INT, @CustomerID INT, @Custo

我正在用C#.Net制作一个桌面应用程序,并想在Sql server中制作一个存储过程。它应该首先检查表是否存在,如果存在,它应该在表中插入值,否则创建表,表名将从winForm中动态获取,就像2019年的表应该是2019年的表,接下来它应该创建table2020,依此类推

CREATE PROCEDURE SaveOrderByYear(@tableName varchar(50),@SaleOrderID    INT,
    @CustomerID     INT,
    @CustomerName   NVARCHAR(100),
    @CustomerNameU  NVARCHAR(100),
    @SaleManID      INT,
    @SaleManName    NVARCHAR(100),
    @SaleManNameU   NVARCHAR(100),
    @SaleExecutiveID        INT,
    @SaleExecutiveName  NVARCHAR(100),
    @SaleExecutiveNameU NVARCHAR(100),
    @SaleMonth      INT,
    @SaleYear       INT,
    @SaleDate       DATE,
    @SaleTime       TIME(2),
    @CreatedBy      INT,
    @CreatedName    NVARCHAR(100),
    @CreatedNameU   NVARCHAR(100),
    @CreatedDate    DATE) as begin

IF (object_id(@tableName, 'U') is null)
begin declare @query varchar(1000); set @query = 'create table ' + @tableName + ' (SaleOrderID INT NOT NULL PRIMARY KEY,
                                                                                   CustomerID   INT NOT NULL,
                                                                                   CustomerName NVARCHAR(100) NOT NULL,
                                                                                   CustomerNameU NVARCHAR(100) NOT NULL,
                                                                                   SaleManID INT NOT NULL,
                                                                                   SaleManName NVARCHAR(100) NOT NULL,
                                                                                   SaleManNameU NVARCHAR(100) NOT NULL,
                                                                                   SaleExecutiveID INT NOT NULL,
                                                                                   SaleExecutiveName NVARCHAR(100) NOT NULL,
                                                                                   SaleExecutiveNameU NVARCHAR(100) NOT NULL,
                                                                                   SaleMonth INT NOT NULL,
                                                                                   SaleYear  INT NOT NULL,
                                                                                   SaleDate  DATE NOT NULL,
                                                                                   SaleTime  TIME(2) NOT NULL,
                                                                                   CreatedBy INT NOT NULL,
                                                                                   CreatedName NVARCHAR(100) NOT NULL,
                                                                                   CreatedNameU NVARCHAR(100) NOT NULL,
                                                                                   CreatedDate DATE NOT NULL,
                                                                                   UpdatedBy  INT NULL,
                                                                                   UpdatedName NVARCHAR(100) NULL,
                                                                                   UpdatedNameU NVARCHAR(100) NUll,
                                                                                   UpdatedDate DATE NULL
                                                                                    )' exec (@query) end print @query

set @query = 'insert into ' + @tableName + ' (SaleOrderID,CustomerID,CustomerName,CustomerNameU,
                SaleManID,SaleManName,SaleManNameU,SaleExecutiveID,SaleExecutiveName,SaleExecutiveNameU,
             SaleMonth,SaleYear,SaleDate,SaleTime,CreatedBy,CreatedName,CreatedNameU,CreatedDate,UpdatedBy,
             UpdatedName,UpdatedNameU,UpdatedDate) values (@SaleOrderID,@CustomerID,@CustomerName,@CustomerNameU,@SaleManID,@SaleManName,@SaleManNameU,@SaleExecutiveID,
    @SaleExecutiveName,@SaleExecutiveNameU,@SaleMonth,@SaleYear,@SaleDate,@SaleTime,@CreatedBy,@CreatedName,
    @CreatedNameU,@CreatedDate)' print @query

exec (@query) end
我使用了此代码,但它返回了一些错误。。 像

NVAR附近的语法不正确,必须声明标量变量@SalesOrderID


您可以使用动态查询(execute语句)在SQL server中实现此要求。您需要在SQL存储过程中动态构建查询,可以将表名作为参数传递,也可以在存储过程本身中构建表名。下面是实现您的要求的示例代码。将表名作为参数并检查该表是否不存在的存储过程将创建该表,然后在该表中插入数据。这只是一个示例,演示如何构建此功能。您可以根据需要插入的数据进一步修改表结构和insert语句。如果您还有其他问题,请随时提问

示例代码 创建过程Proc1(@tableName varchar(50)) 作为 开始

如果(object_id(@tableName,'U')为null)
开始 声明@query varchar(1000); set@query='create table'+@tableName+ “(field1 varchar(100))” exec(@query) 结束 打印@query

set@query='插入'+@tableName+ “(字段1)值(“测试数据”)” 打印@query

exec(@query) 结束


--exec Proc1'order2020'

我们可以修复您的SP以使其正常工作,但我将重点介绍我注意到您尝试使用的错误方法,即使用名称中的年份创建同一表的不同版本。这是一个非常糟糕的设计,原因有几个(维护、性能、查询的简单性等)

相反,您应该强制执行的是只创建一个带有
日期
(或
日期时间
)列的表,然后根据需要查询每年/每月

CREATE TABLE SaleOrder (
    SaleOrderID INT NOT NULL PRIMARY KEY,
    CustomerID   INT NOT NULL,
    CustomerName NVARCHAR(100) NOT NULL,
    CustomerNameU NVARCHAR(100) NOT NULL,
    SaleManID INT NOT NULL,
    SaleManName NVARCHAR(100) NOT NULL,
    SaleManNameU NVARCHAR(100) NOT NULL,
    SaleExecutiveID INT NOT NULL,
    SaleExecutiveName NVARCHAR(100) NOT NULL,
    SaleExecutiveNameU NVARCHAR(100) NOT NULL,
    SaleMonth INT NOT NULL,
    SaleYear  INT NOT NULL,
    SaleDate  DATE NOT NULL,
    SaleTime  TIME(2) NOT NULL,
    CreatedBy INT NOT NULL,
    CreatedName NVARCHAR(100) NOT NULL,
    CreatedNameU NVARCHAR(100) NOT NULL,
    CreatedDate DATE NOT NULL,
    UpdatedBy  INT NULL,
    UpdatedName NVARCHAR(100) NULL,
    UpdatedNameU NVARCHAR(100) NUll,
    UpdatedDate DATE NULL,

    SaleOrderDate DATE) -- We will use this new column as example
因此:

SELECT S.* FROM SaleOrder2018 AS S
变成这样:

SELECT S.* FROM SaleOrder AS S WHERE YEAR(S.SaleOrderDate) = 2018
如果插入时不知道应填写的日期,可以从其他日期列中推断:

INSERT INTO SaleOrder (
    /*All Column List*/
    SaleOrderDate)
SELECT (
    /*All Column List*/
    SaleOrderDate = @CreatedDate -- Or @UpdatedDate, or any expression you can use to know the proper date
如果您可能在不同的年份中重复了
SaleOrderID
列的“主键”,则可以使用自动生成的、与业务无关的值作为
primary KEY
(这是非常常见的用法)。您可以将列声明为
IDENTITY

CREATE TABLE SaleOrder (
    SaleOrderAutoID INT IDENTITY PRIMARY KEY,
    SaleOrderID INT NOT NULL -- remove PRIMARY KEY from this one
    /*... other columns*/
    )
使用此选项,您无需在插入前检查表是否存在,SP直接插入数据,而无需使用动态SQL:

CREATE PROCEDURE SaveOrder(
    @SaleOrderID    INT,
    @CustomerID     INT,
    @CustomerName   NVARCHAR(100),
    @CustomerNameU  NVARCHAR(100),
    @SaleManID      INT,
    @SaleManName    NVARCHAR(100),
    @SaleManNameU   NVARCHAR(100),
    @SaleExecutiveID        INT,
    @SaleExecutiveName  NVARCHAR(100),
    @SaleExecutiveNameU NVARCHAR(100),
    @SaleMonth      INT,
    @SaleYear       INT,
    @SaleDate       DATE,
    @SaleTime       TIME(2),
    @CreatedBy      INT,
    @CreatedName    NVARCHAR(100),
    @CreatedNameU   NVARCHAR(100),
    @CreatedDate    DATE) 
AS
BEGIN
    INSERT INTO SaleOrder (
        SaleOrderID,
        CustomerID,
        CustomerName,
        CustomerNameU,
        SaleManID,
        SaleManName,
        SaleManNameU,
        SaleExecutiveID,
        SaleExecutiveName,
        SaleExecutiveNameU,
        SaleMonth,
        SaleYear,
        SaleDate,
        SaleTime,
        CreatedBy,
        CreatedName ,
        CreatedNameU,
        CreatedDate,
        --UpdatedBy,
        --UpdatedName,
        --UpdatedNameU,
        --UpdatedDate,
        SaleOrderDate)
    SELECT
        SaleOrderID = @SaleOrderID,
        CustomerID = @CustomerID,
        CustomerName = @CustomerName,
        CustomerNameU = @CustomerNameU,
        SaleManID = @SaleManID,
        SaleManName = @SaleManName,
        SaleManNameU = @SaleManNameU,
        SaleExecutiveID = @SaleExecutiveID,
        SaleExecutiveName = @SaleExecutiveName,
        SaleExecutiveNameU = @SaleExecutiveNameU,
        SaleMonth = @SaleMonth,
        SaleYear = @SaleYear,
        SaleDate = @SaleDate,
        SaleTime = @SaleTime,
        CreatedBy = @CreatedBy,
        CreatedName = @CreatedName,
        CreatedNameU = @CreatedNameU,
        CreatedDate = @CreatedDate,
        --UpdatedBy = ,
        --UpdatedName,
        --UpdatedNameU,
        --UpdatedDate,
        SaleOrderDate = @SaleDate

END

你能让我们看看你的尝试吗?我什么都没做。我不知道从哪里开始。只想做一个存储过程,在这个过程中,每年都应该创建一个表,表名和年份如order2019、order2020等。试试谷歌SQL Server create table-有很多信息可以帮助您开始。欢迎使用Stack Overflow。虽然这里有丰富的信息,但这个网站不是一个代码编写服务。为了提高你的问题的质量,请出示你对此问题所做研究的证据,包括指向任何有用或听起来可能相关的页面的链接。请向我们展示您尝试过的任何代码以及您收到的结果说明(包括任何错误消息的全文)。按年份创建不同的表是一个非常糟糕的设计,您应该只创建一个带有日期参数的表。我使用了它运行的代码,但当我修改它时会出现一些错误。请阅读我刚刚编辑的问题以了解详细信息。请告诉我如何解决这些错误。您还需要在insert语句中连接其他参数,就像@tablename变量一样