Heim Datenbank MySQL-Tutorial SqlServer调用外部程序实现数据同步

SqlServer调用外部程序实现数据同步

Jun 07, 2016 pm 03:21 PM
sqlserver 同步 extern 实现 数据 程序 调用 首先

首先创建两个数据库:SyncA是数据源,SyncB是对SyncA进行同步的数据库。 在SyncA和SyncB中分别创建Source表和Target表,实际业务中,两张表的结构大多不相同。 然后创建一个类库的项目:MySync(注意项目的版本,Sql08不支持的.net 4.0及更高版本) 下面是同

首先创建两个数据库:SyncA是数据源,SyncB是对SyncA进行同步的数据库。

SqlServer调用外部程序实现数据同步

在SyncA和SyncB中分别创建Source表和Target表,实际业务中,两张表的结构大多不相同。

SqlServer调用外部程序实现数据同步   SqlServer调用外部程序实现数据同步

然后创建一个类库的项目:MySync(注意项目的版本,Sql08不支持的.net 4.0及更高版本)

SqlServer调用外部程序实现数据同步

下面是同步程序代码:

<span>using</span><span> System;
</span><span>using</span><span> System.Data;
</span><span>using</span><span> System.Data.Sql;
</span><span>using</span><span> Microsoft.SqlServer.Server;
</span><span>using</span><span> System.Data.SqlClient;
</span><span>using</span><span> System.Data.SqlTypes;

</span><span>namespace</span><span> MySync
{
    </span><span>public</span> <span>class</span><span> SyncDataBase
    {<br>       [SqlFunction(SystemDataAccess = SystemDataAccessKind.Read, DataAccess = DataAccessKind.Read)]
        </span><span>public</span> <span>static</span> <span>string</span> Sync(<span>string</span><span> strSql)
        {
            </span><span>string</span> result = <span>"</span><span>true</span><span>"</span><span>;

            </span><span>string</span> strConn = <span>@"</span><span>Data Source=localhost;Initial Catalog=SyncB;User ID=sa;Password=123@abc;</span><span>"</span><span>;
            </span><span>try</span><span>
            {
                </span><span>using</span> (SqlConnection connection = <span>new</span><span> SqlConnection(strConn))
                {
                    connection.Open();
                    SqlCommand command </span>= <span>new</span><span> SqlCommand(strSql, connection);
                    command.CommandType </span>=<span> CommandType.Text;
                    command.ExecuteNonQuery();
                    connection.Close();
                }
            }
            </span><span>catch</span><span> (Exception ex)
            {
                result </span>= <span>"</span><span>false:</span><span>"</span> +<span> ex.ToString();
            }

            </span><span>return</span><span> result;
        }
    }
}</span>
Nach dem Login kopieren

接下来要对类库项目进行签名,签名后编译【项目】:

SqlServer调用外部程序实现数据同步

SqlServer调用外部程序实现数据同步

启用CLR功能:默认情况下,Sql Server中的CLR是关闭的,所以我们要执行如下命令打开SyncA数据库的CLR。

<span>exec</span> sp_configure <span>'</span><span>clr enabled</span><span>'</span>,<span>1</span>  
<span>reconfigure</span>  
<span>go</span>
Nach dem Login kopieren

SqlServer调用外部程序实现数据同步

注册DLL:

为了调用我们写的那个方法,需要在SQL Server中注册我们刚刚编译好的那个DLL。在此之前,要知道在这个项目中如果要访问服务器之外的资源是要配置权限的。如果不配置,后面操作中会出现类似下面的错误。我找到的关于授权配置的内容:连接。

SqlServer调用外部程序实现数据同步

创建登录名和密钥,如果程序集有变更,要删除密钥和登录名重新创建:

<span>USE</span><span> master; 
</span><span>GO</span>  
 
<span>CREATE</span> ASYMMETRIC <span>KEY</span> SQLCLRSyncKey <span>FROM</span> EXECUTABLE <span>FILE</span> <span>=</span> <span>'</span><span>C:\MySync.dll</span><span>'</span>  
<span>CREATE</span> LOGIN SQLCLRSyncLogin <span>FROM</span> ASYMMETRIC <span>KEY</span><span> SQLCLRSyncKey   
</span><span>GRANT</span> EXTERNAL ACCESS ASSEMBLY <span>TO</span><span> SQLCLRSyncLogin; 
</span><span>GO</span> 
Nach dem Login kopieren

<span>DROP</span><span> LOGIN SQLCLRSyncLogin
</span><span>DROP</span> ASYMMETRIC <span>KEY</span> SQLCLRSyncKey
Nach dem Login kopieren

创建程序集,DLL变更后要删除重新创建:

<span>USE</span><span> SyncA; 
</span><span>GO</span>  

<span>create</span><span> ASSEMBLY MySync 
</span><span>FROM</span> <span>'</span><span>C:\MySync.dll</span><span>'</span>
<span>WITH</span> PERMISSION_SET <span>=</span><span> EXTERNAL_ACCESS;
</span><span>GO</span> 
Nach dem Login kopieren

然后创建一个函数用于调用这个DLL:

<span>CREATE</span> <span>FUNCTION</span><span> dbo.fun_sync
(  
    </span><span>@strSql</span> <span>nvarchar</span>(<span>max</span><span>)
)
</span><span>RETURNS</span> <span>nvarchar</span>(<span>max</span><span>)  
</span><span>AS</span> EXTERNAL NAME <span>[</span><span>MySync</span><span>]</span>.<span>[</span><span>MySync.SyncDataBase</span><span>]</span>.<span>[</span><span>Sync</span><span>]</span> 
Nach dem Login kopieren

先来测试一下,在SyncA中执行查询:

<span>SELECT</span> dbo.fun_sync(<span>'</span><span>insert into Target(Id,Name,SyncTime) values (null,null,getdate())</span><span>'</span>)
Nach dem Login kopieren

SqlServer调用外部程序实现数据同步

SyncB中添加了一条数据:

SqlServer调用外部程序实现数据同步

下面使用触发器自动的从SyncA中将数据同步到SyncB中,其中的tt表是我临时创建的,用于保存触发器调用返回的结果:

<span>create</span> <span>Trigger</span><span> tr_source
</span><span>on</span> <span>[</span><span>Source</span><span>]</span>
<span>for</span> <span>INSERT</span>

<span>AS</span>
<span>begin</span>
<span>declare</span> <span>@strSql</span> <span>nvarchar</span>(<span>max</span><span>)
</span><span>select</span> <span>@strSql</span><span>=</span><span>'</span><span>insert into Target(Id,Name,SyncTime) values (</span><span>'''</span><span>+</span><span>cast</span>(Id <span>as</span> <span>nvarchar</span>)<span>+</span><span>'''</span><span>,</span><span>'''</span><span>+</span>Title<span>+</span><span>'''</span><span>,getdate())</span><span>'</span> <span>from</span><span> inserted

</span><span>--</span><span>执行</span>
<span>declare</span> <span>@result</span> <span>nvarchar</span>(<span>max</span><span>)
</span><span>select</span> <span>@result</span><span>=</span>dbo.fun_sync(<span>@strSql</span><span>)

</span><span>insert</span> <span>into</span> tt(tt) <span>values</span> (<span>@result</span><span>)
</span><span>end</span>
Nach dem Login kopieren

直接执行函数没有问题,但是触发器去调用函数执行却出现异常:

<span>false:System.Data.SqlClient.SqlException: 其他会话正在使用事务的上下文。     
在 System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)     
在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)     
在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)     
在 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)     
在 System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest)     
在 System.Data.SqlClient.SqlInternalConnectionTds.PropagateTransactionCookie(Byte[] cookie)     
在 System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx)     
在 System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx)     
在 System.Data.SqlClient.SqlInternalConnectionTds.Activate(Transaction transaction)    
在 System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction transaction)     
在 System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)     
在 System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)     
在 System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)     
在 System.Data.SqlClient.SqlConnection.Open()     
在 MySync.SyncDataBase.Sync(String strSql)</span>
Nach dem Login kopieren

这个错误中包含了一个false值,说明触发器调用时已经可以走到DLL这一步了。考虑到在查询中直接执行函数,走到DLL这一步是没有错误的。那么错误就发生在触发器和DLL调用产生的冲突,冲突在访问数据库上面,再深入的原因,我也没有找到。

下面使用另外一种方式实现同步,因为错误是触发器和DLL的数据库访问冲突,那么我就绕过数据库的访问。将触发器产生的SQL脚本保存到某个目录下面,然后通过其他程序监听这个目录,执行脚本文件,实现同步。

类库代码

<span>using</span><span> System;
</span><span>using</span><span> System.Data;
</span><span>using</span><span> System.Data.Sql;
</span><span>using</span><span> Microsoft.SqlServer.Server;
</span><span>using</span><span> System.Data.SqlClient;
</span><span>using</span><span> System.Data.SqlTypes;
</span><span>using</span><span> System.IO;

</span><span>namespace</span><span> MySync
{
    </span><span>public</span> <span>class</span><span> SyncDataBase
    {
        [SqlFunction(SystemDataAccess </span>= SystemDataAccessKind.Read, DataAccess =<span> DataAccessKind.Read)]
        </span><span>public</span> <span>static</span> <span>string</span> Sync(<span>string</span><span> strSql)
        {
            </span><span>string</span> result = <span>"</span><span>true</span><span>"</span><span>;

            </span><span>try</span><span>
            {
                </span><span>if</span> (!Directory.Exists(<span>"</span><span>c:\\SyncLog</span><span>"</span><span>))
                {
                    Directory.CreateDirectory(</span><span>"</span><span>c:\\SyncLog</span><span>"</span><span>);
                }
                </span><span>string</span> fileName = <span>@"</span><span>c:\\SyncLog\\</span><span>"</span> + DateTime.Now.ToString(<span>"</span><span>yyyyMMddHHmmss</span><span>"</span>) + <span>"</span><span>.txt</span><span>"</span><span>;
                </span><span>if</span> (<span>File.Exists(fileName))
                    File.Delete(fileName);

                </span><span>using</span> (StreamWriter sw =<span> File.CreateText(fileName))
                {
                    sw.WriteLine(strSql);
                }
            }
            </span><span>catch</span><span> (Exception ex)
            {
                result </span>= <span>"</span><span>false:</span><span>"</span> +<span> ex.ToString();
            }

            </span><span>return</span><span> result;
        }
    }
}</span>
Nach dem Login kopieren

另外创建一个监听程序:MyListen

<span>using</span><span> System;
</span><span>using</span><span> System.Data;
</span><span>using</span><span> System.Data.Sql;
</span><span>using</span><span> System.Data.SqlClient;
</span><span>using</span><span> System.Data.SqlTypes;
</span><span>using</span><span> System.Configuration;
</span><span>using</span><span> System.Threading;
</span><span>using</span><span> System.IO;

</span><span>namespace</span><span> MyListen
{
    </span><span>class</span><span> Program
    {
        </span><span>static</span> <span>void</span> Main(<span>string</span><span>[] args)
        {
            </span><span>string</span> connSync = ConfigurationManager.ConnectionStrings[<span>"</span><span>connSync</span><span>"</span><span>].ToString();
            </span><span>string</span> filePath = ConfigurationManager.AppSettings[<span>"</span><span>filePath</span><span>"</span><span>];
            </span><span>while</span> (<span>true</span><span>)
            {
                </span><span>//</span><span>所有txt文件</span>
                <span>string</span>[] fileList = DirFile.GetFileNames(filePath, <span>"</span><span>*.txt</span><span>"</span>, <span>true</span><span>);
                </span><span>foreach</span> (<span>var</span> f <span>in</span><span> fileList)
                {
                    </span><span>string</span> strSql = <span>""</span><span>;
                    </span><span>using</span> (StreamReader sr = <span>new</span><span> StreamReader(f))
                    {
                        </span><span>string</span><span> line;
                        </span><span>while</span> ((line = sr.ReadLine()) != <span>null</span><span>)
                        {
                            strSql </span>+= line + <span>"</span> <span>"</span><span>;
                        }
                        sr.Close();
                    }
                    </span><span>try</span><span>
                    {
                        </span><span>using</span> (SqlConnection connection = <span>new</span><span> SqlConnection(connSync))
                        {
                            connection.Open();
                            SqlCommand command </span>= <span>new</span><span> SqlCommand(strSql, connection);
                            command.CommandType </span>=<span> CommandType.Text;
                            command.ExecuteNonQuery();
                            connection.Close();
                        }
                    }
                    </span><span>catch</span><span> (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                    }
                    File.Delete(f);
                }
                </span><span>//</span><span>每10秒扫描一次</span>
                Thread.Sleep(<span>5</span> * <span>1000</span><span>);
            }
        }
    }
}</span>
Nach dem Login kopieren

只要将监听程序打开,就可以实现对数据的同步。项目和数据库下载。

参考:

http://msdn.microsoft.com/zh-cn/library/Microsoft.SqlServer.Server.SqlFunctionAttribute_properties(v=vs.100).aspx

http://blog.sina.com.cn/s/blog_59c41d0d0100esjn.html

http://www.cnblogs.com/wshcn/archive/2011/12/02/2271630.html

http://www.cnblogs.com/edong/archive/2010/03/10/1682172.html

http://www.cnblogs.com/hsrzyn/archive/2013/05/28/1976555.html

 

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Java-Tutorial
1664
14
PHP-Tutorial
1268
29
C#-Tutorial
1243
24
So machen Sie Google Maps zur Standardkarte im iPhone So machen Sie Google Maps zur Standardkarte im iPhone Apr 17, 2024 pm 07:34 PM

Die Standardkarte auf dem iPhone ist Maps, Apples proprietärer Geolokalisierungsanbieter. Obwohl die Karte immer besser wird, funktioniert sie außerhalb der Vereinigten Staaten nicht gut. Im Vergleich zu Google Maps hat es nichts zu bieten. In diesem Artikel besprechen wir die möglichen Schritte, um Google Maps als Standardkarte auf Ihrem iPhone zu nutzen. So machen Sie Google Maps zur Standardkarte auf dem iPhone. Das Festlegen von Google Maps als Standardkarten-App auf Ihrem Telefon ist einfacher als Sie denken. Befolgen Sie die nachstehenden Schritte – Erforderliche Schritte – Sie müssen Gmail auf Ihrem Telefon installiert haben. Schritt 1 – Öffnen Sie den AppStore. Schritt 2 – Suchen Sie nach „Gmail“. Schritt 3 – Klicken Sie auf neben der Gmail-App

So importieren Sie eine MDF-Datei in SQL Server So importieren Sie eine MDF-Datei in SQL Server Apr 08, 2024 am 11:41 AM

Die Importschritte sind wie folgt: Kopieren Sie die MDF-Datei in das Datenverzeichnis von SQL Server (normalerweise C:\Programme\Microsoft SQL Server\MSSQL\DATA). Öffnen Sie in SQL Server Management Studio (SSMS) die Datenbank und wählen Sie Anhängen aus. Klicken Sie auf die Schaltfläche „Hinzufügen“ und wählen Sie die MDF-Datei aus. Bestätigen Sie den Datenbanknamen und klicken Sie auf die Schaltfläche OK.

So lösen Sie das Problem, dass das genannte Objekt bereits in der SQLServer-Datenbank vorhanden ist So lösen Sie das Problem, dass das genannte Objekt bereits in der SQLServer-Datenbank vorhanden ist Apr 05, 2024 pm 09:42 PM

Für Objekte mit demselben Namen, die bereits in der SQL Server-Datenbank vorhanden sind, müssen folgende Schritte ausgeführt werden: Bestätigen Sie den Objekttyp (Tabelle, Ansicht, gespeicherte Prozedur). Mit IF NOT EXISTS kann die Erstellung übersprungen werden, wenn das Objekt leer ist. Wenn das Objekt Daten enthält, verwenden Sie einen anderen Namen oder ändern Sie die Struktur. Verwenden Sie DROP, um vorhandene Objekte zu löschen (Vorsicht, Sicherung empfohlen). Suchen Sie nach Schemaänderungen, um sicherzustellen, dass keine Verweise auf gelöschte oder umbenannte Objekte vorhanden sind.

Uhr-App fehlt im iPhone: So beheben Sie das Problem Uhr-App fehlt im iPhone: So beheben Sie das Problem May 03, 2024 pm 09:19 PM

Fehlt die Uhr-App auf Ihrem Telefon? Datum und Uhrzeit werden weiterhin in der Statusleiste Ihres iPhones angezeigt. Ohne die Uhr-App können Sie jedoch die Weltzeituhr, die Stoppuhr, den Wecker und viele andere Funktionen nicht nutzen. Daher sollte die Reparatur der fehlenden Uhr-App ganz oben auf Ihrer To-Do-Liste stehen. Diese Lösungen können Ihnen bei der Lösung dieses Problems helfen. Lösung 1 – Platzieren Sie die Uhr-App. Wenn Sie versehentlich die Uhr-App von Ihrem Startbildschirm entfernt haben, können Sie die Uhr-App wieder an ihrem Platz platzieren. Schritt 1 – Entsperren Sie Ihr iPhone und wischen Sie nach links, bis Sie zur Seite „App-Bibliothek“ gelangen. Schritt 2 – Suchen Sie als Nächstes im Suchfeld nach „Uhr“. Schritt 3 – Wenn Sie unten in den Suchergebnissen „Uhr“ sehen, halten Sie die Taste und gedrückt

So stellen Sie eine versehentlich gelöschte Datenbank in SQL Server wieder her So stellen Sie eine versehentlich gelöschte Datenbank in SQL Server wieder her Apr 05, 2024 pm 10:39 PM

Wenn Sie eine SQL Server-Datenbank versehentlich löschen, können Sie die Datenbankaktivität stoppen; Party-Tools. Bitte sichern Sie Ihre Datenbank regelmäßig und aktivieren Sie die Transaktionsprotokollierung, um Datenverlust zu verhindern.

So überprüfen Sie die SQLServer-Portnummer So überprüfen Sie die SQLServer-Portnummer Apr 05, 2024 pm 09:57 PM

So zeigen Sie die SQL Server-Portnummer an: Öffnen Sie SSMS und stellen Sie eine Verbindung zum Server her. Suchen Sie den Servernamen im Objekt-Explorer, klicken Sie mit der rechten Maustaste darauf und wählen Sie Eigenschaften. Sehen Sie sich auf der Registerkarte „Verbindung“ das Feld „TCP-Port“ an.

Was tun, wenn der SQLServer-Dienst nicht gestartet werden kann? Was tun, wenn der SQLServer-Dienst nicht gestartet werden kann? Apr 05, 2024 pm 10:00 PM

Wenn der SQL Server-Dienst nicht gestartet werden kann, können Sie die folgenden Schritte beheben: Überprüfen Sie das Fehlerprotokoll, um die Grundursache zu ermitteln. Stellen Sie sicher, dass das Dienstkonto über die Berechtigung zum Starten des Dienstes verfügt. Überprüfen Sie, ob Abhängigkeitsdienste ausgeführt werden. Deaktivieren Sie die Antivirensoftware. Reparieren Sie die SQL Server-Installation. Wenn die Reparatur nicht funktioniert, installieren Sie SQL Server neu.

Langsame Internetgeschwindigkeiten für Mobilfunkdaten auf dem iPhone: Korrekturen Langsame Internetgeschwindigkeiten für Mobilfunkdaten auf dem iPhone: Korrekturen May 03, 2024 pm 09:01 PM

Stehen Sie vor einer Verzögerung oder einer langsamen mobilen Datenverbindung auf dem iPhone? Normalerweise hängt die Stärke des Mobilfunk-Internets auf Ihrem Telefon von mehreren Faktoren ab, wie z. B. der Region, dem Mobilfunknetztyp, dem Roaming-Typ usw. Es gibt einige Dinge, die Sie tun können, um eine schnellere und zuverlässigere Mobilfunk-Internetverbindung zu erhalten. Fix 1 – Neustart des iPhone erzwingen Manchmal werden durch einen erzwungenen Neustart Ihres Geräts viele Dinge zurückgesetzt, einschließlich der Mobilfunkverbindung. Schritt 1 – Drücken Sie einfach einmal die Lauter-Taste und lassen Sie sie los. Drücken Sie anschließend die Leiser-Taste und lassen Sie sie wieder los. Schritt 2 – Der nächste Teil des Prozesses besteht darin, die Taste auf der rechten Seite gedrückt zu halten. Lassen Sie das iPhone den Neustart abschließen. Aktivieren Sie Mobilfunkdaten und überprüfen Sie die Netzwerkgeschwindigkeit. Überprüfen Sie es erneut. Fix 2 – Datenmodus ändern 5G bietet zwar bessere Netzwerkgeschwindigkeiten, funktioniert jedoch besser, wenn das Signal schwächer ist

See all articles