1. 程式人生 > >SQL:插入資料的小坑

SQL:插入資料的小坑

在SQL Server中,不管是儲存過程還是自定義函式中,經常需要進行插入資料的操作。在插入資料的時候,很多人選擇如下方式

INSERT INTO DestinationTable
SELECT Column1,Column2,<column3 ,>
FROM SourceTable

這樣插入通常不會出現什麼問題,但是在DestinationTable的表字段發生變化時,就會出現問題,如圖所示的例子

USE [TrustManagement]
GO

/****** Object:  Table [Asset].[TrustAssetPaymentPlan_New]    Script Date: 8/3/2018 9:33:50 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [Asset].[Table_1_New](
	[TrustId] [int] NOT NULL,
	[PoolId] [int] NOT NULL,
	[DimLoanId] [int] NOT NULL,
	[AccountNo] [nvarchar](100) NOT NULL,
	[PaymentTypeId] [int] NULL,
	[PrincipalPaymentType] [nvarchar](100) NULL,
	[InterestPaymentType] [nvarchar](100) NULL,
	[PrincipalPayFrequency] [int] NULL,
	[InterestPayFrequency] [int] NULL,
	[InterestOnlyPayFrequency] [int] NULL,
	[PrincipalTerm] [int] NULL,
	[InterestTerm] [int] NULL,
	[InterestOnlyTerm] [int] NULL,
	[InterestStartDate] [date] NULL,
	[PayCycleStartDate] [date] NULL,
	[LastPayDate] [date] NULL,
	[Term] [int] NULL,
	[Amount] [decimal](19, 6) NULL,
	[InterestRate] [decimal](15, 6) NULL,
	[PayDay] [int] NULL,
	[InterestBasis] [nvarchar](50) NULL,
	[IsInTrust] [int] NULL,
	[PaymentConfigurationTypeId] [int] NULL,
	[CloseDate] [date] NULL,
	[PaymentSchedule] [nvarchar](max) NULL,
	[FeeOutstanding] [decimal](19, 6) NULL,
	[PrincipalPayment] [decimal](38, 2) NULL,
	[LoanStartDate] [date] NULL,
	[InterestFirstPaymentDate] [date] NULL,
	[SecondLastPaymentDate] [date] NULL,
	[LastPaymentDate] [date] NULL,
	[InterestPayment] [decimal](38, 2) NULL,
 CONSTRAINT [PK_Table_1_New] PRIMARY KEY CLUSTERED 
(
	[TrustId] ASC,
	[PoolId] ASC,
	[DimLoanId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO
-------------------------------------------------------------------------------
    INSERT  INTO Asset.Table_1_New
    SELECT 
        TrustId ,
        PoolId ,
        IIF(@TrustId>0, DimLoanid, Id) AS DimLoanid,--To prevent duplicate primary keys when performance test
        AccountNo  ,
        PaymentTypeId  ,
        PrincipalPaymentType  ,
        InterestPaymentType ,
        PrincipalPayFrequency  ,
        InterestPayFrequency ,
        InterestOnlyPayFrequency  ,
        PrincipalTerm ,
        InterestTerm  ,
        InterestOnlyTerm ,
        InterestStartDate  ,
        null as PayCycleStartDate ,
        null as LastPayDate  ,
        Term  ,
        Amount  ,
        InterestRate ,
        iif(PayDay is NULL,datepart(d,CloseDate),PayDay) as PayDay,
        InterestBasis  ,
        IsInTrust  ,
        PaymentConfigurationTypeId,
        CloseDate,
        PaymentSchedule ,
        FeeOutstanding ,
        PrincipalPayment ,
		InterestPayment,
		LoanStartDate,
		InterestFirstPaymentDate,
		SecondLastPaymentDate,
		LastPaymentDate
    FROM #PaymentPlan
    

執行後面的插入語句的時候會發現出現如下錯誤資訊

System.Data.SqlClient.SqlException (0x80131904): Operand type clash: decimal is incompatible with date at Securitisation.Utilities.SQL.UtilSqlRunQueryADONET.RunNonQueryStoredProcedure(String sSPName, List`1 glParameters, String sConnectionString) at BL.TaskProcessService.OperationProvider.RunSP(ITaskAction action) ClientConnectionId:1c312f06-dc7e-453b-b42f-859e5d2541d2 Error Number:206,State:2,Class:16

原因是查詢的結果集欄位順序與目標表的欄位的順序不是一一對應的,出現將decimal型別的資料插入到date型別的欄位中。解決這個問題,最好的辦法就是在插入的時候,列清楚欄位,保證查詢結果集中欄位與要插入資料的欄位一一對應。