I'm trying to write a program that does a bulk insert, and within this bulk insert I am converting all of the data that doesn't parse as its correct data type as null. I still need the rest of the row inserted in there.
This wasn't a problem, but I also need to record where these errors happen. But I'm having a bit of trouble doing this because you cannot insert in a function.
Here is the function I have tried:
CREATE FUNCTION [dbo].[ReplaceNonNumericInt]
(@strText NVARCHAR(100),
@strField nvarchar(100),
@LoanOrShare nvarchar(1))
RETURNS INT
AS
BEGIN
DECLARE @Return as int
IF TRY_CAST(@strText AS INT) > 0
BEGIN
SET @Return = CAST(@strText as int)
END
ELSE BEGIN
IF @LoanOrShare = 'L'
BEGIN
INSERT INTO tblLoan_ImportErrors(Error, Field, Row)
VALUES('Type Conversion Failure', @strField, @@IDENTITY + 1)
SET @Return = NULL
END
SET @Return = NULL
END
RETURN @Return
END
However this does not work because you cannot do insert statements in functions. The solution I have found to this was "use a stored procedure", however I don't know how to get the stored procedure to return like a function. I can't use an output parameter to my knowledge since this is being called from within an insert statement.
Here is the code I'm using to insert the records:
CREATE PROCEDURE [dbo].[sp_insLoans]
@FileLocation nvarchar(500)
AS
CREATE TABLE #tmpLOAN (
[RecordCode] NVARCHAR (100) NULL,
[AccountNum] NVARCHAR (100) NULL,
[MembersName] NVARCHAR (100) NULL,
[MailingAddress] NVARCHAR (100) NULL,
[City] NVARCHAR (100) NULL,
[State] NVARCHAR (100) NULL,
[ZipCode] NVARCHAR (100) NULL,
[OtherStreet] NVARCHAR (100) NULL,
[LoanTypeCode] NVARCHAR (100) NULL,
[PaymentAmt] NVARCHAR(100) NULL,
[PurposeCode] NVARCHAR (100) NULL,
[LoanTerm] NVARCHAR (100) NULL,
[PaymentFreqCode] NVARCHAR (100) NULL,
[DateOfLoan] NVARCHAR(100) NULL,
[OriginalLoanAmt] NVARCHAR(100) NULL,
[InterestRate] NVARCHAR(100) NULL,
[InterestRateCode] NVARCHAR (100) NULL,
[CurrentLoanBal] NVARCHAR(100) NULL,
[DateOfLastActivity] NVARCHAR(100) NULL,
[LastActivityCode] NVARCHAR (100) NULL,
[NextPaymentDueDate] NVARCHAR(100) NULL,
[AccruedInt] NVARCHAR(100) NULL,
[CreditLimit] NVARCHAR(100) NULL,
[SSN] NVARCHAR (100) NULL,
[DaysDelinq] nvarchar(100) NULL,
[Delinq30_59] nvarchar(100) NULL,
[Delinq60_89] nvarchar(100) NULL,
[Delinq90_119] nvarchar(100) NULL,
[Delinq120_plus] nvarchar(100) NULL,
[InsiderCode] NVARCHAR (100) NULL,
[LoanOfficer_CCInit] NVARCHAR (100) NULL,
[CreditScore] nvarchar(100) NULL,
[ChargeOffAmt] NVARCHAR(100) NULL,
[LoanRiskGrade] NVARCHAR (100) NULL,
[RemainingPayments] nvarchar(100) NULL,
[LoanCollateralCode] NVARCHAR (100) NULL,
[LastFileMaintDate] NVARCHAR(100) NULL,
[LastFIleMaintUser] NVARCHAR (100) NULL,
[BranchId] NVARCHAR (100) NULL
)
DECLARE @sql NVARCHAR(4000) = 'BULK INSERT #tmpLOAN FROM ''' + @FileLocation + ''' WITH ( FIELDTERMINATOR ='''+ CHAR(9) +''', ROWTERMINATOR ='''+CHAR(10)+''' )';
exec(@sql)
INSERT INTO tblLOAN(RecordCode,AccountNum,MembersName,MailingAddress,City,[State],ZipCode,OtherStreet,LoanTypeCode,PaymentAmt,PurposeCode,LoanTerm,PaymentFreqCode,DateOfLoan,OriginalLoanAmt,InterestRate,InterestRateCode,CurrentLoanBal,DateOfLastActivity,LastActivityCode,NextPaymentDueDate,AccruedInt,CreditLimit,SSN,DaysDelinq,dbo.Delinq30_59,Delinq60_89,Delinq90_119,Delinq120_plus,InsiderCode,LoanOfficer_CCInit,CreditScore,ChargeOffAmt,LoanRiskGrade,RemainingPayments,LoanCollateralCode,LastFileMaintDate,LastFileMaintUser,BranchId)
SELECT LTRIM(RTRIM(RecordCode)),
LTRIM(RTRIM(AccountNum)),
LTRIM(RTRIM(MembersName)),
LTRIM(RTRIM(MailingAddress)),
LTRIM(RTRIM(City)),
LTRIM(RTRIM([State])),
LTRIM(RTRIM(ZipCode)),
LTRIM(RTRIM(OtherStreet)),
LTRIM(RTRIM(LoanTypeCode)),
dbo.ReplaceNonNumericDecimal((RTRIM(PaymentAmt))),
LTRIM(RTRIM(PurposeCode)),
LTRIM(RTRIM(LoanTerm)),
LTRIM(RTRIM(PaymentFreqCode)),
dbo.DateOrNull((LTRIM(RTRIM(DateOfLoan)))),
dbo.ReplaceNonNumericDecimal(LTRIM(RTRIM(OriginalLoanAmt))),
dbo.ReplaceNonNumericDecimal(LTRIM(RTRIM(InterestRate))),
LTRIM(RTRIM(InterestRateCode)),
dbo.ReplaceNonNumericDecimal(LTRIM(RTRIM(CurrentLoanBal))),
dbo.DateOrNull(DateOfLastActivity),
LTRIM(RTRIM(LastActivityCode)),
dbo.DateOrNull(LTRIM(RTRIM(NextPaymentDueDate))),
dbo.ReplaceNonNumericDecimal(LTRIM(RTRIM(AccruedInt))),
dbo.ReplaceNonNumericDecimal(LTRIM(RTRIM(CreditLimit))),
LTRIM(RTRIM(SSN)),
dbo.ReplaceNonNumericInt(LTRIM(RTRIM(DaysDelinq)),'DaysDelinq','L'),
dbo.ReplaceNonNumericInt(LTRIM(RTRIM(Delinq30_59)),'Delinq30_59','L'),
dbo.ReplaceNonNumericInt(LTRIM(RTRIM(Delinq60_89)),'Delinq60_89','L'),
dbo.ReplaceNonNumericInt(LTRIM(RTRIM(Delinq90_119)),'Delinq90_119','L'),
dbo.ReplaceNonNumericInt(LTRIM(RTRIM(Delinq120_plus)),'Delinq120_plus','L'),
LTRIM(RTRIM(InsiderCode)),
LTRIM(RTRIM(LoanOfficer_CCInit)),
dbo.ReplaceNonNumericInt(LTRIM(RTRIM(CreditScore)),'CreditScore','L'),
dbo.ReplaceNonNumericDecimal(LTRIM(RTRIM(ChargeOffAmt))),
LTRIM(RTRIM(LoanRiskGrade)),
dbo.ReplaceNonNumericInt(LTRIM(RTRIM(RemainingPayments)),'RemainingPayments','L'),
LTRIM(RTRIM(LoanCollateralCode)),
dbo.DateOrNull((RTRIM(LastFileMaintDate))),
LTRIM(RTRIM(LastFileMaintUser)),
LTRIM(RTRIM(BranchId))
FROM #tmpLoan
DROP TABLE #tmpLoan
Is there any way to do what I'm trying to do?
sp_prefix for your stored procedures. Microsoft has reserved that prefix for its own use (see Naming Stored Procedures), and you do run the risk of a name clash sometime in the future. It's also bad for your stored procedure performance. It's best to just simply avoidsp_and use something else as a prefix - or no prefix at all!exceptthe known troublemakers. Aside:@@Identitycan return interesting results in the presence of triggers.Scope_Identity()or anOutputclause are rather more reliable. Using@@Identity + 1has an unpleasant smell.