使用T-SQL中的一个参数将多个值插入多行

时间:2016-04-19 15:16:32

标签: arrays sql-server tsql ms-access sql-insert

我正在构建一个使用Microsoft Access作为前端而SQL Server作为后端的应用程序。

我有一个插入客户信息的存储过程。为每位客户插入的信息之一是他们的信用卡号码。每位客户的信用卡数量可以是1-50。

我打算在VBA中使用动态数组来添加信用卡号码。我遇到的麻烦是我不太确定如何将值传递给存储过程。

我的第一个想法是创建大量参数(CC号1,CC号2,CC号3等),但显然这不是正确的方法。

在将信用卡号添加到动态阵列后,我可以重新调整它以获取我需要插入多少个信用卡号的计数。

最好的方法是将14个信用卡值传递给一个参数并将每个值作为新行插入?

2 个答案:

答案 0 :(得分:1)

不幸的是,AFAIK,VBA不支持表值参数(ADO.NET,但不支持我们必须在Access中使用的vanilla VB6实现)。

您可以通过循环记录集或其他东西向服务器发送函数调用流,但这将会非常缓慢。但是,如果您不介意重复自己,可以发送一个包含一堆EXEC语句的大命令(如果您使用的是DAO,请务必指定SET NOCOUNT ON在查询开始时。)

如果您正在寻找纯SQL解决方案,这就是我针对这些问题采取的策略:

  • 将值数组连接成具有某种分隔符的字符串(例如“,”或“|”)。
  • 将字符串传递给将其转换为值表的函数或查询。
  • INSERTMERGE将值表放入最终目标表。

以下是您可以执行此操作的示例:

SET NOCOUNT ON

DECLARE @x XML;
DECLARE @CreditCards AS TABLE (CreditCardNumber VARCHAR(16));
DECLARE @FinalTable AS TABLE (CreditCardNumber VARCHAR(16));
DECLARE @CreditCardList AS VARCHAR(8000);
DECLARE @Divider AS Varchar(10);

SET @Divider=',';
SET @CreditCardList='1234567890123456,1111111111111111,2222222222222222,123456789012345';

IF NOT @CreditCardList IS NULL 
  BEGIN 
    SELECT @x = CAST('<A>'+ REPLACE(@CreditCardList,@Divider,'</A><A>')+ '</A>' AS XML);
    INSERT INTO 
      @CreditCards            
    SELECT 
      t.value('.', 'varchar(16)') AS inVal
    FROM 
      @x.nodes('/A') AS x(t) ;
  END 

INSERT INTO 
  @FinalTable
SELECT 
  CreditCardNumber
FROM
  @CreditCards 

SELECT * FROM @FinaLTable

XML并不是进行转换的最快方法,但它具有相对简单的优点。 Jeff Moden在他的博客文章Tally OH! An Improved SQL 8K “CSV Splitter” Function中提供了几个相当灵感的方法来解决这个问题。

希望有所帮助!

答案 1 :(得分:0)

使用XML将所有客户信息传递到一个文档中。这样,您可以传递任意数量的参数,并在服务器上将其作为表格进行查询。