Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
Пример Hello World Ready демонстрирует основные операции, которые участвуют в создании, развертывании и тестировании простой хранимой процедуры среды CLR. Готовый к миру компонент можно легко локализовать на разных языках для разных рынков по всему миру, не изменяя исходный код компонента. В этом примере также показано, как возвращать данные через выходной параметр и через запись, которая динамически создается хранимой процедурой и возвращается клиенту. Этот пример почти идентичен примеру Hello World, за исключением того, что это гораздо проще и безопаснее для локализации этого приложения. Для изменения локализованного текста требуется следующее:
Изменение XML-файла (файла .
resx) для конкретного языка и региональных параметров в каталоге ресурсовСоздание файла ресурсов языка и региональных параметров с помощью
resgenСоздание обновленной вспомогательной библиотеки DLL для этого языка и региональных параметров
Удаление и добавление этой сборки в SQL Server
Исходный код и сборка для хранимой процедуры CLR не изменяется.
build.cmd Предоставляется скрипт, демонстрирующий компиляцию и связывание сборок ресурсов. Хотя исходный код для приложения создает диспетчер ресурсов на основе текущей выполняемой сборки, вам не нужно внедрять нейтральные ресурсы языка и региональных параметров в библиотеку DLL, содержащую хранимую процедуру. Это System.Resources.NeutralResourcesLanguage attribute позволяет ресурсам, не зависящим от языка и региональных параметров, существовать в вспомогательной библиотеке DLL. Гораздо лучше использовать отдельную библиотеку DLL для этой цели, чтобы при необходимости добавления или изменения локализованного текста основной библиотеки DLL, содержащей хранимую процедуру CLR, не нужно изменять. Это особенно полезно для определяемых пользователем типов СРЕДЫ CLR, которые могут иметь столбцы и другие зависимости, что затрудняет удаление и повторное добавление типа. Как правило, вспомогательные версии DLL должны совпадать с основной версией сборки. Однако атрибут можно использовать SatelliteContractVersion , чтобы разрешить обновление основной сборки, не обновляя вспомогательные сборки. Дополнительные сведения см ResourceManager . в документации по Microsoft .NET.
Предпосылки
Этот пример работает только с SQL Server 2005 и более поздними версиями.
Чтобы создать и запустить этот проект, необходимо установить следующее программное обеспечение:
SQL Server или SQL Server Express. Вы можете бесплатно получить SQL Server Express на веб-сайте документации и примеров SQL Server Express.
База данных AdventureWorks, доступная на веб-сайте разработчика SQL Server
Пакет SDK для .NET Framework 2.0 или более поздней версии или Microsoft Visual Studio 2005 или более поздней версии. Пакет SDK для .NET Framework можно получить бесплатно.
Кроме того, необходимо выполнить следующие условия:
Экземпляр SQL Server, который вы используете, должен включать интеграцию CLR.
Чтобы включить интеграцию СРЕДЫ CLR, выполните следующие действия.
Включение интеграции со средой CLR
- Выполните следующие команды Transact-SQL:
sp_configure 'clr enabled', 1GORECONFIGUREGOЗамечание
Чтобы включить среду CLR, необходимо иметь
ALTER SETTINGSразрешение на уровне сервера, которое неявно удерживается членамиsysadminролей сервера иserveradminпредопределенных ролей сервера.База данных AdventureWorks должна быть установлена на используемом экземпляре SQL Server.
Если вы не являетесь администратором используемого экземпляра SQL Server, необходимо предоставить администратору разрешение CreateAssembly для завершения установки.
Создание примера
Создайте и запустите пример, выполнив следующие инструкции:
Откройте командную строку Visual Studio или .NET Framework.
При необходимости создайте каталог для примера. В этом примере мы будем использовать C:\MySample.
В c:\MySample создайте
HelloWorld.vb(для примера Visual Basic) илиHelloWorld.cs(для примера C#) и скопируйте соответствующий пример кода Visual Basic или C# (ниже) в файл.В c:\MySample создайте файл
messages.resxи скопируйте пример кода в файл.В c:\MySample создайте файл, сохранив файл
messages.de.resxmessages.resx, какmessages.de.resxпосле изменения строки.<value xml:space="preserve">Hello, World!</value>Чтение
<value xml:space="preserve">Hallo Welt!</value>
В c:\MySample создайте файл, сохранив файл
messages.es.resxmessages.resx, какmessages.es.resxпосле изменения строки.<value xml:space="preserve">Hello, World!</value>Чтение
<value xml:space="preserve">Hola a todos</value>
В c:\MySample создайте файл, сохранив файл
messages.fr.resxmessages.resx, какmessages.fr.resxпосле изменения строки.<value xml:space="preserve">Hello, World!</value>Чтение
<value xml:space="preserve">Bonjour !</value>
В c:\MySample создайте файл, сохранив файл
messages.fr-FR.resxmessages.resx, какmessages.fr-FR.resxпосле изменения строки.<value xml:space="preserve">Hello, World!</value>Чтение
<value xml:space="preserve">Bonjour de France!</value>
В c:\MySample создайте файл, сохранив файл
messages.it.resxmessages.resx, какmessages.it.resxпосле изменения строки.<value xml:space="preserve">Hello, World!</value>Чтение
<value xml:space="preserve">Buongiorno</value>
В c:\MySample создайте файл, сохранив файл
messages.ja.resxmessages.resx, какmessages.ja.resxпосле изменения строки.<value xml:space="preserve">Hello, World!</value>Чтение
<value xml:space="preserve">ã"ã‚"ã«ã¡ã¯</value>
В c:\MySample создайте файл
build.comи скопируйте пример кода в файл.Создайте спутник, выполнив сборку файла в командной строке.
Скомпилируйте пример кода из командной строки, выполнив одно из следующих действий:
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.
Если образец установлен в каталоге другой
C:\MySample\, измените файлInstall.sql, как указано, чтобы указать на это расположение.Развертывание сборки и хранимой процедуры путем выполнения
sqlcmd -E -I -i install.sql
Скопируйте Transact-SQL тестовый скрипт команды в файл и сохраните его как
test.sqlв примере каталога.Выполнение тестового скрипта с помощью следующей команды
sqlcmd -E -I -i test.sql
Скопируйте скрипт очистки Transact-SQL в файл и сохраните его как
cleanup.sqlв примере каталога.Выполнение скрипта с помощью следующей команды
sqlcmd -E -I -i cleanup.sql
Пример кода
Ниже приведены описания кода для этого примера.
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
Это — build.comсборка вспомогательных сборок.
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
Это скрипт установки Transact-SQL (Install.sql), который развертывает сборки и создает хранимую процедуру в базе данных.
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
Это пример test.sql, который проверяет образец, выполняя функции на каждом языковом стандарте.
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
Следующая Transact-SQL удаляет сборки и хранимую процедуру из базы данных.
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