Sql server 动态插入过程

Sql server 动态插入过程,sql-server,tsql,Sql Server,Tsql,我有一个动态插入过程。实际上,我正试图用C#的一个按钮创建所有过程。无论如何,我创建了那个插入过程,但如果isActive为null,它看起来就是这样。所以SQLServer给出了一个错误。有没有办法替换这个coma(,)字符?或者有什么建议 INSERT INTO category ( mainCatId, catname, isActive, ) VALUES ( @mainCatId, @catname, @isActive, ) 看起来是这样的 declare @mainCa

我有一个动态插入过程。实际上,我正试图用C#的一个按钮创建所有过程。无论如何,我创建了那个插入过程,但如果isActive为null,它看起来就是这样。所以SQLServer给出了一个错误。有没有办法替换这个coma(,)字符?或者有什么建议

INSERT INTO category (  mainCatId,  catname, isActive, ) VALUES (  @mainCatId,  @catname, @isActive,  )
看起来是这样的

declare @mainCatId int = 1, @catname nvarchar (50) = NULL, @isActive bit = NULL

DECLARE @sqlQuery nvarchar(4000); 
SET @sqlQuery =     'INSERT INTO category ( ';

IF ( @mainCatId IS NOT NULL )
 SET @sqlQuery = @sqlQuery + ' mainCatId, ';

IF ( @isActive IS NOT NULL )
 SET @sqlQuery = @sqlQuery + ' isActive, ';

SET @sqlQuery = @sqlQuery + ' )';

SET @sqlQuery = @sqlQuery + ' VALUES ( ';

IF ( @mainCatId IS NOT NULL )
 SET @sqlQuery = @sqlQuery + ' @mainCatId, ';

IF ( @catname IS NOT NULL )
 SET @sqlQuery = @sqlQuery + ' @catname, ';

IF ( @isActive IS NOT NULL )
 SET @sqlQuery = @sqlQuery + ' @isActive, ';

SET @sqlQuery = @sqlQuery + ' )';
SET @sqlQuery = @sqlQuery;

不确定您的确切问题,但如果只移动逗号,则不会出现尾随逗号问题:

我还为您的值添加了引号(可能需要根据动态语句的执行方式再次加倍)


不确定您的确切问题,但如果只移动逗号,则不会出现尾随逗号问题:

我还为您的值添加了引号(可能需要根据动态语句的执行方式再次加倍)


如果只想去除尾随字符,可以将其放在脚本中的适当位置:

SET @sqlQuery = LEFT(@sqlQuery, LEN(@sqlquery) - 1)

这将删除尾随空格和之前的最后一个字符。

如果您只想删除尾随字符,可以将其放在脚本中的适当位置:

SET @sqlQuery = LEFT(@sqlQuery, LEN(@sqlquery) - 1)

这将删除尾随空格和之前的最后一个字符。

我会做一些稍微不同的事情。这不是为每个值构建字符串,而是包含完整的SQL语句,您只需传入每个字段的值即可:

declare @mainCatId int = 1, 
    @catname nvarchar (50) = NULL, 
    @isActive bit = NULL

declare @mainCatIdString nvarchar(10)
declare @catnameString nvarchar(50)
declare @isActiveString nvarchar(50) 

DECLARE @sqlQuery nvarchar(4000); 


If @mainCatId is not null
    set @mainCatIdString = cast(@mainCatId as nvarchar(10))
else 
    set @mainCatIdString = ''

If @catname is not null
    set @catnameString = @catname
else 
    set @catnameString = ''

If @isActive is not null
    set @isActiveString = Cast(@isActive as nvarchar(10))
else 
    set @isActiveString = 0

SET @sqlQuery = 'INSERT INTO category 
                (
                    mainCatId, 
                    catname, 
                    isActive
                ) 
                VALUES 
                (
                    ' + @mainCatIdString +',''' 
                        + @catnameString + ''',' 
                        + @isActiveString +')'
 print @sqlQuery
编辑:我不完全明白使用动态查询的原因。这可以在与此类似的存储过程中轻松执行。在此过程中,您将向其传递所有三个参数,然后根据值是否为
null

create procedure test
(
    @mainCatId int = 1, 
    @catname nvarchar (50) = null, 
    @isActive bit = null
)
AS
BEGIN                               
   INSERT INTO Category
   (
       mainCatId, 
       catname, 
       isActive
   ) 
   SELECT IsNull(@mainCatId, 1), 
      IsNull(@catname, ''), 
      IsNull(@isActive, 0)
END

我会做一些稍微不同的事情。这不是为每个值构建字符串,而是包含完整的SQL语句,您只需传入每个字段的值即可:

declare @mainCatId int = 1, 
    @catname nvarchar (50) = NULL, 
    @isActive bit = NULL

declare @mainCatIdString nvarchar(10)
declare @catnameString nvarchar(50)
declare @isActiveString nvarchar(50) 

DECLARE @sqlQuery nvarchar(4000); 


If @mainCatId is not null
    set @mainCatIdString = cast(@mainCatId as nvarchar(10))
else 
    set @mainCatIdString = ''

If @catname is not null
    set @catnameString = @catname
else 
    set @catnameString = ''

If @isActive is not null
    set @isActiveString = Cast(@isActive as nvarchar(10))
else 
    set @isActiveString = 0

SET @sqlQuery = 'INSERT INTO category 
                (
                    mainCatId, 
                    catname, 
                    isActive
                ) 
                VALUES 
                (
                    ' + @mainCatIdString +',''' 
                        + @catnameString + ''',' 
                        + @isActiveString +')'
 print @sqlQuery
编辑:我不完全明白使用动态查询的原因。这可以在与此类似的存储过程中轻松执行。在此过程中,您将向其传递所有三个参数,然后根据值是否为
null

create procedure test
(
    @mainCatId int = 1, 
    @catname nvarchar (50) = null, 
    @isActive bit = null
)
AS
BEGIN                               
   INSERT INTO Category
   (
       mainCatId, 
       catname, 
       isActive
   ) 
   SELECT IsNull(@mainCatId, 1), 
      IsNull(@catname, ''), 
      IsNull(@isActive, 0)
END

为什么您要费心使用动态SQL,并动态构建此查询,而忽略具有空值的列?如果这些列可以为NULL,并且您希望存储
NULL
,为什么不说:

INSERT dbo.category(mainCatId,catname,isActive) 
  VALUES(@mainCatId,@catname,@isActive);
这将在参数为NULL的列中输入NULL值。如果它们被指定为NOTNULL或具有默认值,则可以更简单地构造动态SQL:

declare @mainCatId int = 1, @catname nvarchar (50) = NULL, @isActive bit = NULL

DECLARE @sql NVARCHAR(4000);

SELECT @sql = N'';

SET @sql = N'INSERT dbo.category(mainCatId,catname,isActive) 
  VALUES(' + COALESCE(RTRIM(@mainCatId), 'DEFAULT')
   + ',' + COALESCE(N'''' 
   + REPLACE(@catname, '''', '''''') + '''', 'DEFAULT')
   + ',' + COALESCE(RTRIM(@isActive), 'DEFAULT')
   + ');';

EXEC sp_executesql @sql;

为什么您要费心使用动态SQL,并动态构建此查询,而忽略具有空值的列?如果这些列可以为NULL,并且您希望存储
NULL
,为什么不说:

INSERT dbo.category(mainCatId,catname,isActive) 
  VALUES(@mainCatId,@catname,@isActive);
这将在参数为NULL的列中输入NULL值。如果它们被指定为NOTNULL或具有默认值,则可以更简单地构造动态SQL:

declare @mainCatId int = 1, @catname nvarchar (50) = NULL, @isActive bit = NULL

DECLARE @sql NVARCHAR(4000);

SELECT @sql = N'';

SET @sql = N'INSERT dbo.category(mainCatId,catname,isActive) 
  VALUES(' + COALESCE(RTRIM(@mainCatId), 'DEFAULT')
   + ',' + COALESCE(N'''' 
   + REPLACE(@catname, '''', '''''') + '''', 'DEFAULT')
   + ',' + COALESCE(RTRIM(@isActive), 'DEFAULT')
   + ');';

EXEC sp_executesql @sql;

在这种情况下,如果用户不输入mainCatId,将会发生什么情况。它以,catname,isActive开头。所以问题又来了。在这种情况下,如果用户不输入mainCatId会发生什么。它以,catname,isActive开头。问题又来了。捕捉得好,但第一个insert语句也是动态的,实际上它不取决于if-else语句。因为例如,用户可能经常使用catname或isActive变量。所以用户只发送maincatId和catname。所以我不需要插入isActive变量。因为它可以是空的。我不知道我是否清楚?@kad1r我不完全理解为什么你首先需要这是一个动态的陈述。如果您创建一个存储过程来插入数据,您只需传入所需的值。我有一个自由职业者项目,您可以选择数据库,它会动态创建所有存储过程,我只想执行动态插入过程,如筛选选择过程。因为我想也许这样更好,我不知道。你有什么建议吗?我必须用这种普通的(经典的)方法吗?很好,但第一个insert语句也是动态的,实际上它不取决于if-else语句。因为例如,用户可能经常使用catname或isActive变量。所以用户只发送maincatId和catname。所以我不需要插入isActive变量。因为它可以是空的。我不知道我是否清楚?@kad1r我不完全理解为什么你首先需要这是一个动态的陈述。如果您创建一个存储过程来插入数据,您只需传入所需的值。我有一个自由职业者项目,您可以选择数据库,它会动态创建所有存储过程,我只想执行动态插入过程,如筛选选择过程。因为我想也许这样更好,我不知道。你有什么建议吗?我必须以常规(经典)方式执行吗?您甚至需要将其作为sql字符串执行吗?你不能创建一个存储过程,将每个参数传递给它,然后选择这些值,就像我在编辑中所做的那样吗?只是想知道什么是更好的过程。@如果您想硬编码默认值,那么BlueFoot可以工作。问题是,如果列不是带有默认值的null,并且默认值以后会更改,那么现在必须在两个地方更改它们。我给OP的好处是怀疑,这是有原因的,这是在动态SQL中进行的。@BlueFoot作为一个旁白,我也希望这样的东西能够工作,以避免动态SQL,但事实并非如此:
如果@mainCatId为NULL,则默认为ELSE@mainCatId END
您甚至需要将其作为sql字符串执行吗?你不能创建一个存储过程,将每个参数传递给它,然后选择这些值,就像我在编辑中所做的那样吗?只是想知道什么是更好的过程。@如果您想硬编码默认值,那么BlueFoot可以工作。问题在于,如果列不是带有默认值的null,那么默认值将在以后更改