Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Im Beispiel "Hello World Ready" werden die grundlegenden Vorgänge veranschaulicht, die beim Erstellen, Bereitstellen und Testen einer einfachen, auf common language runtime (CLR) basierenden gespeicherten Prozedur (Common Language Runtime) beteiligt sind. Eine weltweit einsatzbereite Komponente kann problemlos in verschiedene Sprachen für verschiedene Märkte auf der ganzen Welt lokalisiert werden, ohne den Quellcode der Komponente zu ändern. In diesem Beispiel wird auch veranschaulicht, wie Daten über einen Ausgabeparameter und einen Datensatz zurückgegeben werden, der dynamisch von der gespeicherten Prozedur erstellt und an den Client zurückgegeben wird. Dieses Beispiel ist fast identisch mit dem Hello World-Beispiel, es sei denn, es ist viel einfacher und sicherer, diese Anwendung zu lokalisieren. Um lokalisierten Text zu ändern, ist Folgendes erforderlich:
Ändern einer XML-Datei (der DATEI
resx) für die bestimmte Kultur im RessourcenverzeichnisErstellen der Ressourcendatei der Kultur mithilfe von
resgenErstellen der aktualisierten Satelliten-DLL für diese Kultur
Ablegen und Hinzufügen dieser Assembly in SQL Server
Der Quellcode und die Assembly für die gespeicherte CLR-Prozedur selbst ändern sich nicht. Es wird ein build.cmd Skript bereitgestellt, das veranschaulicht, wie die Ressourcenassemblys kompiliert und verknüpft werden. Obwohl der Quellcode für die Anwendung einen Ressourcen-Manager erstellt, der auf der derzeit ausgeführten Assembly basiert, müssen Sie die kulturneutralen Ressourcen nicht in die DLL einbetten, die die gespeicherte Prozedur enthält. Dies System.Resources.NeutralResourcesLanguage attribute ermöglicht es den kulturneutralen Ressourcen in einer Satelliten-DLL zu existieren. Es ist viel besser, eine separate DLL für diesen Zweck zu verwenden, damit die primäre DLL, die die gespeicherte CLR-Prozedur enthält, nicht geändert werden muss, wenn lokalisierter Text hinzugefügt oder geändert werden muss. Dies ist besonders nützlich für benutzerdefinierte CLR-Typen, die Möglicherweise Spalten und andere Abhängigkeiten aufweisen, wodurch das Ablegen und erneute Hinzufügen des Typs erschwert wird. Ordinarily, the satellite DLL versions must be identisch to the main assembly version. Sie können das SatelliteContractVersion Attribut jedoch verwenden, um zuzulassen, dass die Hauptassembly aktualisiert wird, ohne auch die Satellitenassemblys zu aktualisieren. Weitere Informationen finden Sie in der Microsoft .NET-Dokumentation in der ResourceManager Klasse.
Voraussetzungen
Dieses Beispiel funktioniert nur mit SQL Server 2005 und höheren Versionen.
Um dieses Projekt zu erstellen und auszuführen, muss die folgende Software installiert sein:
SQL Server oder SQL Server Express. Sie können SQL Server Express kostenlos über die SQL Server Express-Dokumentation und -Beispiele-Website beziehen.
Die AdventureWorks-Datenbank, die auf der SQL Server Developer-Website verfügbar ist
.NET Framework SDK 2.0 oder höher oder Microsoft Visual Studio 2005 oder höher. Sie können .NET Framework SDK kostenlos erhalten.
Darüber hinaus müssen die folgenden Bedingungen erfüllt sein:
Die verwendete SQL Server-Instanz muss die CLR-Integration aktiviert haben.
Führen Sie die folgenden Schritte aus, um die CLR-Integration zu aktivieren:
Aktivieren der CLR-Integration
- Führen Sie die folgenden Transact-SQL Befehle aus:
sp_configure 'clr enabled', 1GORECONFIGUREGOHinweis
Um CLR zu aktivieren, müssen
ALTER SETTINGSSie über die Berechtigung auf Serverebene verfügen, die implizit von Mitgliedern dersysadminundserveradminfesten Serverrollen gehalten wird.Die AdventureWorks-Datenbank muss auf der verwendeten SQL Server-Instanz installiert werden.
Wenn Sie kein Administrator für die verwendete SQL Server-Instanz sind, müssen Sie über einen Administrator verfügen, der Ihnen die Berechtigung "CreateAssembly" erteilt, um die Installation abzuschließen.
Erstellen des Beispiels
Erstellen und Ausführen des Beispiels mithilfe der folgenden Anweisungen:
Öffnen Sie eine Visual Studio- oder .NET Framework-Eingabeaufforderung.
Erstellen Sie bei Bedarf ein Verzeichnis für Ihr Beispiel. In diesem Beispiel verwenden wir C:\MySample.
Erstellen Sie
HelloWorld.vbin c:\MySample (für das Visual Basic-Beispiel) oder (für das C#-Beispiel) undHelloWorld.cskopieren Sie den entsprechenden Visual Basic- oder C#-Beispielcode (unten) in die Datei.Erstellen Sie in "c:\MySample" die Datei
messages.resx, und kopieren Sie den Beispielcode in die Datei.Erstellen Sie in "c:\MySample" die Datei
messages.de.resx, indem Sie die Dateimessages.resxwiemessages.de.resxnach dem Ändern der Zeile speichern.<value xml:space="preserve">Hello, World!</value>So lesen Sie
<value xml:space="preserve">Hallo Welt!</value>
Erstellen Sie in "c:\MySample" die Datei
messages.es.resx, indem Sie die Dateimessages.resxwiemessages.es.resxnach dem Ändern der Zeile speichern.<value xml:space="preserve">Hello, World!</value>So lesen Sie
<value xml:space="preserve">Hola a todos</value>
Erstellen Sie in "c:\MySample" die Datei
messages.fr.resx, indem Sie die Dateimessages.resxwiemessages.fr.resxnach dem Ändern der Zeile speichern.<value xml:space="preserve">Hello, World!</value>So lesen Sie
<value xml:space="preserve">Bonjour !</value>
Erstellen Sie in "c:\MySample" die Datei
messages.fr-FR.resx, indem Sie die Dateimessages.resxwiemessages.fr-FR.resxnach dem Ändern der Zeile speichern.<value xml:space="preserve">Hello, World!</value>So lesen Sie
<value xml:space="preserve">Bonjour de France!</value>
Erstellen Sie in "c:\MySample" die Datei
messages.it.resx, indem Sie die Dateimessages.resxwiemessages.it.resxnach dem Ändern der Zeile speichern.<value xml:space="preserve">Hello, World!</value>So lesen Sie
<value xml:space="preserve">Buongiorno</value>
Erstellen Sie in "c:\MySample" die Datei
messages.ja.resx, indem Sie die Dateimessages.resxwiemessages.ja.resxnach dem Ändern der Zeile speichern.<value xml:space="preserve">Hello, World!</value>So lesen Sie
<value xml:space="preserve">ã"ã‚"ã«ã¡ã¯</value>
Erstellen Sie in "c:\MySample" die Datei
build.com, und kopieren Sie den Beispielcode in die Datei.Erstellen Sie die Satellitenassembler, indem Sie den Dateibuild an der Eingabeaufforderung ausführen.
Kompilieren Sie den Beispielcode aus der Eingabeaufforderung der Befehlszeile, indem Sie eine der folgenden Aktionen ausführen:
Vbc /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll,C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll,C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /out:HelloWorldReady.dll /target:library HelloWorld.vbCsc /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.XML.dll /out:HelloWorldReady.dll /target:library Hello.csCopy the tsql installation code into a file and save it as Install.sql in the sample directory.
Wenn das Beispiel in einem anderen
C:\MySample\Verzeichnis installiert ist, bearbeiten Sie die DateiInstall.sqlwie angegeben, um auf diesen Speicherort zu verweisen.Bereitstellen der Assembly und der gespeicherten Prozedur durch Ausführen
sqlcmd -E -I -i install.sql
Kopieren Sie Transact-SQL Testbefehlsskripts in eine Datei, und speichern Sie es im
test.sqlBeispielverzeichnis.Ausführen des Testskripts mit dem folgenden Befehl
sqlcmd -E -I -i test.sql
Kopieren Sie das Transact-SQL Bereinigungsskripts in eine Datei, und speichern Sie es im
cleanup.sqlBeispielverzeichnis.Ausführen des Skripts mit dem folgenden Befehl
sqlcmd -E -I -i cleanup.sql
Beispielcode
Im Folgenden finden Sie die Codeauflistungen für dieses Beispiel.
C#
using System;
using System.Data;
using System.Data.Sql;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Globalization;
using System.Threading;
using System.Resources;
using System.Reflection;
using System.Runtime.CompilerServices;
[assembly: System.Resources.NeutralResourcesLanguage("", System.Resources.UltimateResourceFallbackLocation.Satellite)]
[assembly: System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.RequestMinimum)]
[assembly: System.Runtime.ConstrainedExecution.ReliabilityContract(System.Runtime.ConstrainedExecution.Consistency.MayCorruptInstance, System.Runtime.ConstrainedExecution.Cer.None)]
public sealed partial class StoredProcedures
{
private StoredProcedures()
{
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters"), Microsoft.SqlServer.Server.SqlProcedure]
public static void HelloWorldReady(string culture, out string greeting)
{
ResourceManager rm
= new ResourceManager("Messages",
Assembly.GetExecutingAssembly());
string message = rm.GetString("HelloWorld", CultureInfo.GetCultureInfo(culture));
Microsoft.SqlServer.Server.SqlMetaData columnInfo
= new Microsoft.SqlServer.Server.SqlMetaData("Column1", SqlDbType.NVarChar, 24);
SqlDataRecord greetingRecord
= new SqlDataRecord(new Microsoft.SqlServer.Server.SqlMetaData[] { columnInfo });
greetingRecord.SetString(0, message);
SqlContext.Pipe.Send(greetingRecord);
greeting = message;
}
}
Visual Basic
Imports System
Imports System.Data
Imports System.Data.Sql
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server
Imports System.Globalization
Imports System.Resources
Imports System.Reflection
Imports System.Runtime.InteropServices
<Assembly: AssemblyVersion("1.0.*")>
<Assembly: System.Runtime.InteropServices.ComVisible(False)>
<Assembly: System.CLSCompliant(True)>
<Assembly: System.Resources.NeutralResourcesLanguage("", System.Resources.UltimateResourceFallbackLocation.Satellite)>
<Assembly: System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.RequestMinimum)>
<Assembly: System.Runtime.ConstrainedExecution.ReliabilityContract(System.Runtime.ConstrainedExecution.Consistency.WillNotCorruptState, Runtime.ConstrainedExecution.Cer.None)>
Partial Public NotInheritable Class StoredProcedures
Private Sub New()
End Sub
<Microsoft.SqlServer.Server.SqlProcedure()> _
Public Shared Sub HelloWorldReady(ByVal culture As String, ByRef greeting As String)
Dim rm As New ResourceManager("Messages", Assembly.GetExecutingAssembly())
Dim message As String = rm.GetString("HelloWorld", CultureInfo.GetCultureInfo(culture))
Dim columnInfo As New Microsoft.SqlServer.Server.SqlMetaData("Column1", _
SqlDbType.NVarChar, 24)
Dim greetingRecord As New SqlDataRecord(New _
Microsoft.SqlServer.Server.SqlMetaData() {columnInfo})
greetingRecord.SetString(0, message)
SqlContext.Pipe.Send(greetingRecord)
greeting = message
End Sub
End Class
Dies ist build.com, die die Satellitenassemblys erstellt.
resgen Messages.resx
resgen Messages.de.resx
resgen Messages.es.resx
resgen Messages.fr.resx
resgen Messages.fr-Fr.resx
resgen Messages.it.resx
resgen Messages.ja.resx
if not exist de/ mkdir de
if not exist es/ mkdir es
if not exist fr/ mkdir fr
if not exist fr-FR/ mkdir fr-FR
if not exist it/ mkdir it
if not exist ja/ mkdir ja
al /t:lib /culture:de /embed:Messages.de.resources /out:de\HelloWorldReady.resources.dll
al /t:lib /culture:es /embed:Messages.es.resources /out:es\HelloWorldReady.resources.dll
al /t:lib /culture:fr /embed:Messages.fr.resources /out:fr\HelloWorldReady.resources.dll
al /t:lib /culture:fr-FR /embed:Messages.fr-FR.resources /out:fr-FR\HelloWorldReady.resources.dll
al /t:lib /culture:it /embed:Messages.it.resources /out:it\HelloWorldReady.resources.dll
al /t:lib /culture:ja /embed:Messages.ja.resources /out:ja\HelloWorldReady.resources.dll
al /t:lib /culture:"" /embed:Messages.resources /out:HelloWorldReady.resources.dll
Dies ist das Transact-SQL Installationsskripts (Install.sql), das die Assemblys bereitstellt und die gespeicherte Prozedur innerhalb der Datenbank erstellt.
USE AdventureWorks
GO
-- Drop existing sproc and assembly if any.
IF EXISTS (SELECT * FROM sys.procedures WHERE [name] = 'usp_HelloWorldReady')
DROP PROCEDURE usp_HelloWorldReady;
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'HelloWorldReady')
DROP ASSEMBLY HelloWorldReady;
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'HelloWorldReady.resources.neutral')
DROP ASSEMBLY [HelloWorldReady.resources.neutral]
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'HelloWorldReady.resources.de')
DROP ASSEMBLY [HelloWorldReady.resources.de]
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'HelloWorldReady.resources.es')
DROP ASSEMBLY [HelloWorldReady.resources.es]
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'HelloWorldReady.resources.fr')
DROP ASSEMBLY [HelloWorldReady.resources.fr]
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'HelloWorldReady.resources.fr-FR')
DROP ASSEMBLY [HelloWorldReady.resources.fr-FR]
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'HelloWorldReady.resources.it')
DROP ASSEMBLY [HelloWorldReady.resources.it]
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'HelloWorldReady.resources.ja')
DROP ASSEMBLY [HelloWorldReady.resources.ja]
GO
DECLARE @SamplesPath nvarchar(1024)
-- You may need to modify the value of this variable if you have installed the sample someplace other than the default location.
Set @SamplesPath = N'C:\MySample\'
-- Add the assembly and CLR integration based stored procedure
CREATE ASSEMBLY HelloWorldReady
FROM @SamplesPath + 'HelloWorldReady.dll'
WITH permission_set = Safe;
CREATE ASSEMBLY [HelloWorldReady.resources.neutral]
FROM @SamplesPath + 'HelloWorldReady.resources.dll'
WITH permission_set = Safe;
CREATE ASSEMBLY [HelloWorldReady.resources.de]
FROM @SamplesPath + '\de\HelloWorldReady.resources.dll'
WITH permission_set = Safe;
CREATE ASSEMBLY [HelloWorldReady.resources.es]
FROM @SamplesPath + '\es\HelloWorldReady.resources.dll'
WITH permission_set = Safe;
CREATE ASSEMBLY [HelloWorldReady.resources.fr]
FROM @SamplesPath + '\fr\HelloWorldReady.resources.dll'
WITH permission_set = Safe;
CREATE ASSEMBLY [HelloWorldReady.resources.fr-FR]
FROM @SamplesPath + '\fr-FR\HelloWorldReady.resources.dll'
WITH permission_set = Safe;
CREATE ASSEMBLY [HelloWorldReady.resources.it]
FROM @SamplesPath + '\it\HelloWorldReady.resources.dll'
WITH permission_set = Safe;
CREATE ASSEMBLY [HelloWorldReady.resources.ja]
FROM @SamplesPath + '\ja\HelloWorldReady.resources.dll'
WITH permission_set = Safe;
GO
CREATE PROCEDURE usp_HelloWorldReady
(
@Culture NVarchar(12),
@Greeting NVarchar(24) OUTPUT
)
AS EXTERNAL NAME HelloWorldReady.StoredProcedures.HelloWorldReady;
GO
USE master;
GO
Dies ist test.sql, was das Beispiel testet, indem die Funktionen auf jedem Gebietsschema ausgeführt werden.
USE AdventureWorks
GO
DECLARE @GreetingDe nvarchar(24);
DECLARE @GreetingDe_CH nvarchar(24);
DECLARE @GreetingEn nvarchar(24);
DECLARE @GreetingEs nvarchar(24);
DECLARE @GreetingFr nvarchar(24);
DECLARE @GreetingFr_FR nvarchar(24);
DECLARE @GreetingIt nvarchar(24);
DECLARE @GreetingJa nvarchar(24);
--German as spoken anywhere in the world (the neutral German culture)
EXEC usp_HelloWorldReady 'de', @GreetingDe OUTPUT;
--German as spoken in Switzerland. Because we don't have a specific assembly
--for this case, the .NET Framework will automatically fall back to the neutral German culture DLL.
EXEC usp_HelloWorldReady 'de-CH', @GreetingDe_CH OUTPUT;
EXEC usp_HelloWorldReady 'en', @GreetingEn OUTPUT;
EXEC usp_HelloWorldReady 'es', @GreetingEs OUTPUT;
--French as spoken anywhere in the world (the neutral French culture)
EXEC usp_HelloWorldReady 'fr', @GreetingFr OUTPUT
--French as spoken in France. Since we do have a specific assembly for this case, a specific
--greeting is provided from that DLL. The neutral French culture DLL is not used in this case.
EXEC usp_HelloWorldReady 'fr-FR', @GreetingFr_FR OUTPUT
EXEC usp_HelloWorldReady 'it', @GreetingIt OUTPUT;
EXEC usp_HelloWorldReady 'ja', @GreetingJa OUTPUT;
SELECT @GreetingDe AS OUTPUT_PARAMETER_DE;
SELECT @GreetingDe_CH AS OUTPUT_PARAMETER_De_CH;
SELECT @GreetingEn AS OUTPUT_PARAMETER_EN;
SELECT @GreetingEs AS OUTPUT_PARAMETER_ES;
SELECT @GreetingFr AS OUTPUT_PARAMETER_FR;
SELECT @GreetingFr_FR AS OUTPUT_PARAMETER_Fr_FR;
SELECT @GreetingIt AS OUTPUT_PARAMETER_IT;
SELECT @GreetingJa AS OUTPUT_PARAMETER_JA;
GO
Im folgenden Transact-SQL werden die Assemblys und die gespeicherte Prozedur aus der Datenbank entfernt.
USE AdventureWorks;
GO
-- Drop existing sproc and assembly if any.
IF EXISTS (SELECT * FROM sys.procedures WHERE [name] = 'usp_HelloWorldReady')
DROP PROCEDURE usp_HelloWorldReady;
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'HelloWorldReady')
DROP ASSEMBLY HelloWorldReady;
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'HelloWorldReady.resources.neutral')
DROP ASSEMBLY [HelloWorldReady.resources.neutral]
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'HelloWorldReady.resources.de')
DROP ASSEMBLY [HelloWorldReady.resources.de]
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'HelloWorldReady.resources.es')
DROP ASSEMBLY [HelloWorldReady.resources.es]
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'HelloWorldReady.resources.fr')
DROP ASSEMBLY [HelloWorldReady.resources.fr]
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'HelloWorldReady.resources.fr-FR')
DROP ASSEMBLY [HelloWorldReady.resources.fr-FR]
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'HelloWorldReady.resources.it')
DROP ASSEMBLY [HelloWorldReady.resources.it]
GO
IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'HelloWorldReady.resources.ja')
DROP ASSEMBLY [HelloWorldReady.resources.ja]
GO
USE master;
GO
Siehe auch
Verwendungsszenarien und Beispiele für Common Language Runtime (CLR)-Integration