![](/img/trans.png)
[英]Access 2010 or SQL Server 2008 Export Query to Custom Text File
[英]SSIS 2008 : Export SQL Data to Access Database 2010 Table
我正在創建一個新的SSIS 2008 ETL報告,該報告將從SQL Server中讀取數據並將其附加到ACCESS 2010數據庫表中。 當訪問表中有一個標識列時,如何將記錄追加到現有訪問表中?
我當前的解決方案有一個帶SQL的OLE DB源,可讀取數據。 它連接到數據轉換任務,然后連接到OLE DB目標任務。 訪問表中的標識字段名為“ Id”,它是一個自動編號字段。
當Access表為空時,我能夠使用OLE DB目標插入值。 問題與身份字段以及表中是否已有記錄有關。
因此,問題在於我的Id列始終從1開始,這意味着由於引擎認為我正在嘗試插入重復的鍵而收到錯誤消息。
我創建了一個SQL任務,該任務從表中讀取最大ID並將其存儲到變量中,但是現在我一直試圖找出如何在數據流導出過程中使用此值。
當表中已經有記錄時,有人可以告訴我如何將數據插入到Access DB中嗎?
為清楚起見進行了編輯。 我已經添加了以下用於獲取所需SQL記錄的SQL。 請注意,我不在SQL中包含ID身份字段:
DECLARE @STARTDATE DATETIME = (SELECT CONVERT(VARCHAR(25),DATEADD(DD,-(DAY(DATEADD(MM,4,GETDATE()))-1),
DATEADD(MM,4,GETDATE())),101))
DECLARE @ENDDATE DATETIME = (SELECT CONVERT(VARCHAR(25),DATEADD(DD,-(DAY(DATEADD(MM,5,GETDATE()))),
DATEADD(MM,5,GETDATE())),101))
SELECT DISTINCT
ISNULL(CONVERT(VARCHAR(3),PP.LOBCD),'CPP') 'LOB_Name_Product'
, POLICYID 'Policy_#'
, P.PRODUCERID 'Agent_#'
, CONVERT(VARCHAR(14),POLICYEFFDT,101) 'Policy_Eff_Date'
, CONVERT(VARCHAR(14),TS.POLICYEXPDT,101) 'Policy_Exp_Date'
, CONVERT(NUMERIC(15,2),TS.TERMPREMAMT) 'Inforce_Prem_Sum'
, REPLACE(CONVERT(CHAR(100),REPLACE(REPLACE(N.INSUREDNM,CHAR(10),' '),CHAR(13),'')),',',' ') AS 'Insured_Name'
, REPLACE(P.PRODUCERNM1TX,',',' ') AS 'Agent_Name'
, PD.PREDSTATECD 'Policy_State'
, REPLACE(II.ADDRLINE1TX ,',',' ') AS 'Insured_Address_1'
, REPLACE(ISNULL(II.ADDRLINE2TX,''),',',' ') AS 'Insured_Address_2'
, II.CITYNM 'Insured_City'
, II.STATECD 'Insured_State'
, CASE WHEN LEN(RTRIM(II.ZIPCD)) > 5 THEN (SUBSTRING(II.ZIPCD,1,5) + '-' + SUBSTRING(II.ZIPCD,6,5))
ELSE II.ZIPCD
END 'Insured_Zip'
, REPLACE(P.PRODUCERADDRLINE1TX,',',' ') AS 'Agent_Address_1'
, REPLACE(ISNULL(P.PRODUCERADDRLINE2TX,''),',',' ') AS 'Agent_Address_2'
, P.PRODUCERCITYNM 'Agent_City'
, P.STATECD 'Agent_State'
, CASE WHEN LEN(RTRIM(P.ZIPCD)) > 5 THEN SUBSTRING(RTRIM(P.ZIPCD),1,5) + '-' + SUBSTRING(RTRIM(P.ZIPCD),6,5)
ELSE P.ZIPCD
END 'Agent_Zip'
, CONVERT(VARCHAR(10), GETDATE(), 101) AS 'Upload_Date'
, 'Open' AS 'Status'
FROM COPOLICYPOINTER PP
JOIN COTRANSACTIONSUMMARY TS ON TS.SYSTEMASSIGNID = PP.SYSTEMASSIGNID
AND TS.TRANSSEQNO = ( SELECT MAX(TRANSSEQNO) FROM COTRANSACTIONSUMMARY TS2
WHERE TS2.SYSTEMASSIGNID = TS.SYSTEMASSIGNID)
AND TS.TRANSEFFDT = ( SELECT MAX(TRANSEFFDT) FROM COTRANSACTIONSUMMARY TS2
WHERE TS2.SYSTEMASSIGNID = TS.SYSTEMASSIGNID)
JOIN COPOLICYDETAIL PD ON TS.SYSTEMASSIGNID = PD.SYSTEMASSIGNID
AND PD.TRANSSEQNO = ( SELECT MAX(TRANSSEQNO) FROM COPRODUCER PD2
WHERE PD2.SYSTEMASSIGNID = PD.SYSTEMASSIGNID)
JOIN COPRODUCER P ON P.SYSTEMASSIGNID = TS.SYSTEMASSIGNID
AND P.TRANSSEQNO = ( SELECT MAX(TRANSSEQNO) FROM COPRODUCER P2
WHERE P2.SYSTEMASSIGNID = P.SYSTEMASSIGNID)
JOIN COINSUREDNAME N ON N.SYSTEMASSIGNID = P.SYSTEMASSIGNID
AND N.TRANSSEQNO = ( SELECT MAX(TRANSSEQNO) FROM COINSUREDNAME N2
WHERE N2.SYSTEMASSIGNID = N.SYSTEMASSIGNID)
JOIN COINSUREDINFO II ON II.SYSTEMASSIGNID = N.SYSTEMASSIGNID
AND II.TRANSSEQNO = ( SELECT MAX(TRANSSEQNO) FROM COINSUREDINFO I2
WHERE I2.SYSTEMASSIGNID = II.SYSTEMASSIGNID)
WHERE TS.POLICYEXPDT BETWEEN @STARTDATE AND @ENDDATE
AND PP.CANCEFFDT IS NULL
AND PD.PREDSTATECD IN ('CT', 'RI', 'GA','NH','NY')
ORDER BY POLICYID
結果鏈接到數據轉換任務。
然后,將數據轉換任務鏈接到OLE DB目標任務。
OLE DB目標任務使用連接到Access數據庫的OLE DB提供程序。 此數據庫中的表之一稱為MasterTable,它具有一個名為ID的自動編號字段。
我在下面添加了整個工作流程的屏幕截圖。
我找到了一種方法來做我需要的事情,所以我將答案發布在這里,以防它對其他人有幫助。 我將總結以下步驟,然后發布代碼。 我正在使用SSIS 2008。
我從在此站點上找到的一個相關答案中得出了這個答案: 在C#中將10萬條記錄插入MDB文件的最快方法是什么?
創建數據流任務
在數據流任務中,使用您的SQL代碼創建OLE Db源。 該查詢將為您提供要放入訪問表中的結果。
一旦開始運行SQL,就創建了一個數據轉換任務,並將大多數列轉換為unicode(日期列除外)。 請注意轉換器的“輸出別名”列中的名稱。 這些是您在下面顯示的C#腳本任務中使用的名稱。
將結果保存到記錄集目標。 創建記錄集時,“組件屬性”選項卡上有一個名為VariableName的字段。 在此放置一個變量。 此變量將保存SQL查詢的結果。 我將其命名為“ rsSourceTable”。 C#代碼將讀取此變量以獲取結果集。
一旦數據流任務開始工作,就創建一個C#腳本任務。 我創建了幾個與腳本任務一起使用的變量。
只讀變量:
AccessPath-保存Access文件所在的路徑。
rsSourceTable-保存我們的數據流任務結果的變量。
讀/寫變量:MasterTableRowCount-我使用它可以很容易地報告在日志文件和電子郵件任務中插入的文件數。
6.腳本任務的c#代碼如下所示。 我不必為此添加任何引用。
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.Data.OleDb;
namespace ST_afd8e3cca5534e51ba5855e82f502e92.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
public void Main()
{
OleDbConnection myConnection = new OleDbConnection();
try
{
string accessPath = Dts.Variables["AccessPath"].Value.ToString();
string materTableId = Dts.Variables["MasterTableId"].Value.ToString();
myConnection.ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + accessPath;
DataTable dt = new DataTable();
OleDbDataAdapter adapter = new OleDbDataAdapter();
adapter.Fill(dt, Dts.Variables["User::rsSourceTable"].Value);
int rowCount = 0;
if (dt.Rows.Count > 0)
{
rowCount = dt.Rows.Count;
Dts.Variables["MasterTableRowCount"].Value.ToString();
myConnection.Open();
//1. When building the INSERT statement, remember to enclose column names in square brackets. This prevents errors because Access allows special characters in column names and OLE DB doesn't
//2. Also remember that the order the column names appear in the INSERT statement is important for the code that adds parameters below.
//3. To prevent an error, the INSERT statement is first constructed with a ? for each parameter. The parameter is replaced with the
// appropriate column name in the for loop below.
string insertString = "INSERT INTO MasterTable ([LOB_Name_Product], [Policy_#], [Policy_State], [Policy_Eff_Date], [Policy_Exp_Date], [Insured_Name], [Insured_Address_1], ";
insertString += "[Insured_Address_2], [Insured_City], [Agent_#], [Agent_Name], [Inforce_Prem_Sum], [Status], [Upload_date], [Insured_Zip], [Insured_State], [Agent_Address_1], [Agent_Address_2], [Agent_City], [Agent_Zip], [Agent_State])";
insertString += " Values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
OleDbCommand cmmd = new OleDbCommand(insertString, myConnection);
if (myConnection.State == ConnectionState.Open)
{
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //LOB_Name_Product
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Policy_#
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Policy_State
cmmd.Parameters.Add("?", OleDbType.DBDate, 10); //Policy_Eff_Date
cmmd.Parameters.Add("?", OleDbType.DBDate, 10); //Policy_Exp_Date
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Insured_Name
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Insured_Address_1
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Insured_Address_2
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Insured_City
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Agent_#
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Agent_Name
cmmd.Parameters.Add("?", OleDbType.Currency, 255); //Inforce_Prem_Sum
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Status
cmmd.Parameters.Add("?", OleDbType.Date, 10); //Upload_date
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Insured_Zip
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Insured_State
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Agent_Address_1
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Agent_Address_2
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Agent_City
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Agent_Zip
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Agent_State
cmmd.Prepare();
OleDbTransaction trans = myConnection.BeginTransaction();
cmmd.Transaction = trans;
foreach(DataRow dr in dt.Rows)
{
cmmd.Parameters[0].Value = dr["Copy of LOB_Name_Product"];
cmmd.Parameters[1].Value = dr["Copy of Policy_#"];
cmmd.Parameters[2].Value = dr["Copy of Policy_State"];
cmmd.Parameters[3].Value = dr["Policy_Eff_Date"];
cmmd.Parameters[4].Value = dr["Policy_Exp_Date"];
cmmd.Parameters[5].Value = dr["Copy of Insured_Name"];
cmmd.Parameters[6].Value = dr["Copy of Insured_Address_1"];
cmmd.Parameters[7].Value = dr["Copy of Insured_Address_2"];
cmmd.Parameters[8].Value = dr["Copy of Insured_City"];
cmmd.Parameters[9].Value = dr["Copy of Agent_#"];
cmmd.Parameters[10].Value = dr["Copy of Agent_Name"];
cmmd.Parameters[11].Value = dr["Copy of Inforce_Prem_Sum"];
cmmd.Parameters[12].Value = "Open";
cmmd.Parameters[13].Value = DateTime.Today.ToString("d");
cmmd.Parameters[14].Value = dr["Copy of Insured_Zip"];
cmmd.Parameters[15].Value = dr["Copy of Insured_State"];
cmmd.Parameters[16].Value = dr["Copy of Agent_Address_1"];
cmmd.Parameters[17].Value = dr["Copy of Agent_Address_2"];
cmmd.Parameters[18].Value = dr["Copy of Agent_City"];
cmmd.Parameters[19].Value = dr["Copy of Agent_Zip"];
cmmd.Parameters[20].Value = dr["Copy of Agent_State"];
cmmd.ExecuteNonQuery();
}
trans.Commit();
myConnection.Close();
Dts.TaskResult = (int)ScriptResults.Success; //add logging here for successful operation
}
else
Dts.TaskResult = (int)ScriptResults.Failure;
}
else
Dts.TaskResult = (int)ScriptResults.Success; //add logging here for no records
}
catch (OleDbException oleEx)
{
myConnection.Close();
Dts.TaskResult = (int)ScriptResults.Failure; //add logging here for unable to connect
}
catch (Exception ex)
{
myConnection.Close();
Dts.TaskResult = (int)ScriptResults.Failure; //add logging here for any other error
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.