如何使用表值用户定义函数来填充另一个表列

时间:2015-03-21 21:51:36

标签: sql sql-server

您好我设法创建了一个我在这里找到的函数。我需要将此Element列的数据填充到另一个表列。我似乎找不到方法你能看看我的吗?很大的问题。

   ALTER FUNCTION [dbo].[func_Split] 
    (   
    @DelimitedString    varchar(8000),
    @Delimiter              varchar(100) 
    )
RETURNS @tblArray TABLE
    (
    ElementID   int IDENTITY(1,1),  -- Array index
    Element     varchar(1000)               -- Array element contents
    )
AS
BEGIN

-- Local Variable Declarations
-- ---------------------------
DECLARE @FinaLResult varchar(max)
DECLARE @Index      smallint,
                @Start      smallint,
                @DelSize    smallint

SET @Delimiter = '='

SET @DelSize = LEN(@Delimiter)

-- Loop through source string and add elements to destination table array
-- ----------------------------------------------------------------------

WHILE LEN(@DelimitedString) > 0
BEGIN

    SET @Index = CHARINDEX(@Delimiter, @DelimitedString)


    IF @Index = 0 
        BEGIN

            INSERT INTO
                @tblArray 
                (Element)
            VALUES
                (LTRIM(RTRIM(@DelimitedString)))             

            BREAK


   END


  ELSE IF @Delimiter = '='
  BEGIN

  INSERT INTO
                    @tblArray 
                    (Element)
                VALUES
                    (SUBSTRING(@DelimitedString,CHARINDEX('=',@DelimitedString)+1,(CHARINDEX('&',@DelimitedString)-(CHARINDEX('=',@DelimitedString)+1))))
            SET @Delimiter='&'

  END

    ELSE 
        BEGIN

            INSERT INTO
                @tblArray 
                (Element)
            VALUES
                (LTRIM(RTRIM(SUBSTRING(@DelimitedString, 1,@Index - 1))))

                --(RIGHT((LTRIM(RTRIM(SUBSTRING(@DelimitedString, 1,@Index - 1)))),LEN((LTRIM(RTRIM(SUBSTRING(@DelimitedString, 1,@Index - 1)))))-CHARINDEX('=',(LTRIM(RTRIM(SUBSTRING(@DelimitedString, 1,@Index - 1)))))))

            SET @Start = @Index + @DelSize
            SET @DelimitedString = SUBSTRING(@DelimitedString, @Start , LEN(@DelimitedString) - @Start + 1)             

            SET @DelimitedString=(RIGHT(@DelimitedString,LEN(@DelimitedString)-CHARINDEX('=',@DelimitedString)))


            --SET @Delimiter='&'

            END

END

RETURN

END

这是我使用该功能的方式,但这不是我想要的方式

 DECLARE @SQLStr varchar(MAX)
SELECT @SQLStr = 'CountryName=UK&Status=Success&QueryID=232919474&NetworkCode=23430&Organisation=mobile'

SELECT
    *
FROM
    dbo.func_split(@SQLStr, '&')

我也写了一个存储过程。我正在使用这个SP来调用函数并填充tbl_HLRProceeData表的列。

ALTER TRIGGER [dbo].[HLRProcessTableFilled] ON [dbo].[tbl_CRM_TempResult]
AFTER INSERT
AS
    --DECLARE @TaskID INT = 0

-- DECLARE @i INT = 1

-- DECLARE @count INT

 DECLARE @TempResultID int
 DECLARE @HLRResult varchar(max)
 DECLARE @QueryID VARCHAR(max)


SET @HLRResult = '';
SET @QueryID = '';




IF NOT EXISTS(SELECT QueryID 
              FROM [WebReg].[dbo].[tbl_HLR_ProcessedData]
              WHERE QueryID = @QueryID)



DECLARE @ProcessedDataHeaderID int
DECLARE @UploadExcelDetailID int
DECLARE @Status varchar(100)
DECLARE @MobileCountry varchar(75)
DECLARE @MobileCountryISO varchar(50)
DECLARE @MobileNetwork varchar(100)
DECLARE @NetType varchar(50)
DECLARE @MobileNetworkCode varchar(50)
DECLARE @Location varchar(50)
DECLARE @ErrorCode varchar(10)
DECLARE @ErrorDescription varchar(100)
DECLARE @Ported bit
DECLARE @PortedFrom varchar(100)
DECLARE @PortedFrom2 varchar(100)
DECLARE @FileRefId int
DECLARE @CheckDate datetime
DECLARE @CreateUserId int
DECLARE @MSISDN varchar(20)
DECLARE @Organisation varchar(1000)


BEGIN
                INSERT INTO [WebReg].[dbo].[tbl_HLR_ProcessedData]
               ([ProcessedDataHeaderID],
                [UploadExcelDetailID]      
               ,[QueryID]
               ,[HlrStatus]
               ,[MobileCountry]
               ,[MobileCountryISO]
               ,[MobileNetworkCode]
               ,[MobileNetwork]
               ,[NetType]
               ,[Location]
               ,[ErrorCode]
               ,[ErrorDescription]
               ,[Ported]
               ,[PortedFrom]
               ,[PortedFrom2]
               ,[FileRefId]
               ,[CheckDate]
               ,[CreateUserId]
               ,[MSISDN]
               ,[Organisation])

VALUES
               (@ProcessedDataHeaderID,
                @UploadExcelDetailID
               ,@QueryID
               ,@HLRResult
               ,NULL
               ,@MobileCountryISO
               ,@MobileNetworkCode
               ,@MobileNetwork
               ,@NetType
               ,@Location
               ,@ErrorCode
               ,@ErrorDescription
               ,@Ported
               ,@PortedFrom
               ,@PortedFrom2
               ,@FileRefId
               ,@CheckDate
               ,@CreateUserId
               ,@MSISDN
               ,@Organisation);

END

ALTER TRIGGER [dbo].[HLRProcessTableFilled] ON [dbo].[tbl_CRM_TempResult]
AFTER INSERT
AS
    --DECLARE @TaskID INT = 0

-- DECLARE @i INT = 1

-- DECLARE @count INT

 DECLARE @TempResultID int
 DECLARE @HLRResult varchar(max)
 DECLARE @QueryID VARCHAR(max)


SET @HLRResult = '';
SET @QueryID = '';




IF NOT EXISTS(SELECT QueryID 
              FROM [WebReg].[dbo].[tbl_HLR_ProcessedData]
              WHERE QueryID = @QueryID)



DECLARE @ProcessedDataHeaderID int
DECLARE @UploadExcelDetailID int
DECLARE @Status varchar(100)
DECLARE @MobileCountry varchar(75)
DECLARE @MobileCountryISO varchar(50)
DECLARE @MobileNetwork varchar(100)
DECLARE @NetType varchar(50)
DECLARE @MobileNetworkCode varchar(50)
DECLARE @Location varchar(50)
DECLARE @ErrorCode varchar(10)
DECLARE @ErrorDescription varchar(100)
DECLARE @Ported bit
DECLARE @PortedFrom varchar(100)
DECLARE @PortedFrom2 varchar(100)
DECLARE @FileRefId int
DECLARE @CheckDate datetime
DECLARE @CreateUserId int
DECLARE @MSISDN varchar(20)
DECLARE @Organisation varchar(1000)


BEGIN
                INSERT INTO [WebReg].[dbo].[tbl_HLR_ProcessedData]
               ([ProcessedDataHeaderID],
                [UploadExcelDetailID]      
               ,[QueryID]
               ,[HlrStatus]
               ,[MobileCountry]
               ,[MobileCountryISO]
               ,[MobileNetworkCode]
               ,[MobileNetwork]
               ,[NetType]
               ,[Location]
               ,[ErrorCode]
               ,[ErrorDescription]
               ,[Ported]
               ,[PortedFrom]
               ,[PortedFrom2]
               ,[FileRefId]
               ,[CheckDate]
               ,[CreateUserId]
               ,[MSISDN]
               ,[Organisation])

VALUES
               (@ProcessedDataHeaderID,
                @UploadExcelDetailID
               ,@QueryID
               ,@HLRResult
               ,NULL
               ,@MobileCountryISO
               ,@MobileNetworkCode
               ,@MobileNetwork
               ,@NetType
               ,@Location
               ,@ErrorCode
               ,@ErrorDescription
               ,@Ported
               ,@PortedFrom
               ,@PortedFrom2
               ,@FileRefId
               ,@CheckDate
               ,@CreateUserId
               ,@MSISDN
               ,@Organisation);


END

只有我不知道如何从SP调用func_Split函数的Element值,所以我可以填写tbl_HLR_ProcessData表的列值。我真的很抱歉我的大问题,有人可以帮我解决问题吗?任何帮助都会受到赞赏。

1 个答案:

答案 0 :(得分:0)

我真的不明白你在做什么。但是,您的表函数返回行,您的触发器将一次处理1行或更多行,因为sql server每个语句调用一次。所以你试图处理一个记录是错误的。

你能做的是:

CREATE FUNCTION dbo.funcSplit
      ( @DelimitedString  varchar(8000)
      , @Searchword       varchar(20) = ' ' 
      ) 
  RETURNS TABLE
  AS
  RETURN 
  ( select sw, p2.ps, p2.pe, ss
    from ( values (@DelimitedString, @Searchword) ) v (d, sw)
    outer apply ( 
      -- find index of search word in DelimitedString 
      select ps = charindex(sw, d, 1)
      ) p1
    outer apply ( 
      -- find value with searching for first '=' and '&' after searchword 
      select pe = charindex('&', d, p1.ps)
           , ps = charindex('=', d, p1.ps) + 1 
           , l  = len(sw)
      ) p2  
    outer apply ( 
      -- find value with searching for first '=' and '&' after searchword 
      select ss = substring(d, p2.ps, p2.pe - p2.ps)
      -- make sure the found searchword is indeed the whole word and ands with =
      where p1.ps + l + 1 = p2.ps 
        and p2.pe > 0
      union all
            -- find value with searching for first '=' and '&' after searchword 
      select ss = substring(d, p2.ps, len(d) - p2.ps)
      -- make sure the found searchword is indeed the whole word and ands with =
      where p1.ps + l + 1 = p2.ps 
        and p2.pe = 0
      ) ss
  ); 

在您的触发器中,您将调用

INSERT INTO [WebReg].[dbo].[tbl_HLR_ProcessedData]
( ...
, QueryID
, ...
, MobileNetworkCode
, ...
)    
SELECT ... 
, sw1.ss
, ...
, sw2.ss
, ...
from inserted i
outer apply ( select * from dbo.funcSplit(i.d, 'QueryID') ) sw1
outer apply ( select * from dbo.funcSplit(i.d, 'NetworkCode') ) sw2

您必须将i.d替换为要拆分的字符串的列名。