Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O exemplo Hello World Ready demonstra as operações básicas envolvidas na criação, implantação e teste de um procedimento armazenado baseado em integração clr (common language runtime) pronto para o mundo simples. Um componente pronto para o mundo pode ser facilmente localizado em diferentes idiomas para diferentes mercados ao redor do mundo sem alterar o código-fonte do componente. Este exemplo também demonstra como retornar dados por meio de um parâmetro de saída e por meio de um registro, que é construído dinamicamente pelo procedimento armazenado e retornado ao cliente. Este exemplo é quase idêntico ao Exemplo do Hello World, exceto que é muito mais fácil e seguro localizar esse aplicativo. Para alterar o texto localizado, é necessário o seguinte:
Alterando um arquivo XML (o arquivo .
resx) para a cultura específica no diretório de recursosCriando o arquivo de recursos da cultura usando
resgenCriando a DLL satélite atualizada para essa cultura
Descartando e adicionando esse assembly no SQL Server
O código-fonte e o assembly do próprio procedimento armazenado CLR não são alterados. Um build.cmd script é fornecido que demonstra como compilar e vincular os assemblies de recursos. Embora o código-fonte do aplicativo crie um gerenciador de recursos com base no assembly em execução no momento, você não precisa inserir os recursos neutros de cultura na DLL que contém o procedimento armazenado. Permite System.Resources.NeutralResourcesLanguage attribute que os recursos neutros de cultura existam em uma DLL satélite. É muito melhor usar uma DLL separada para essa finalidade para que, quando o texto localizado precisar ser adicionado ou alterado, a DLL primária que contém o procedimento armazenado CLR não precise ser alterada. Isso é especialmente útil para tipos clr definidos pelo usuário que podem ter colunas e outras dependências, o que tornaria difícil remover e adicionar novamente o tipo. Normalmente, as versões de DLL satélite devem ser idênticas à versão principal do assembly. No entanto, você pode usar o SatelliteContractVersion atributo para permitir que o assembly principal seja atualizado sem atualizar os assemblies satélites também. Para obter mais informações, consulte a ResourceManager classe na documentação do Microsoft .NET.
Pré-requisitos
Este exemplo funciona apenas com o SQL Server 2005 e versões posteriores.
Para criar e executar este projeto, o seguinte software deve ser instalado:
SQL Server ou SQL Server Express. Você pode obter o SQL Server Express gratuitamente no site de Documentação e Exemplos do SQL Server Express
O banco de dados AdventureWorks que está disponível no site do Desenvolvedor do SQL Server
SDK do .NET Framework 2.0 ou posterior ou Microsoft Visual Studio 2005 ou posterior. Você pode obter o SDK do .NET Framework gratuitamente.
Além disso, as seguintes condições devem ser atendidas:
A instância do SQL Server que você está usando deve ter a integração CLR habilitada.
Para habilitar a integração do CLR, execute as seguintes etapas:
Habilitando integração CLR
- Execute os seguintes comandos de Transact-SQL:
sp_configure 'clr enabled', 1GORECONFIGUREGOObservação
Para habilitar o CLR, você deve ter
ALTER SETTINGSpermissão de nível de servidor, que é mantida implicitamente por membros das funções de servidor fixas esysadmindeserveradminmembros.O banco de dados AdventureWorks deve ser instalado na instância do SQL Server que você está usando.
Se você não for um administrador da instância do SQL Server que está usando, deverá ter um administrador concedendo a você a permissão CreateAssembly para concluir a instalação.
Compilando o exemplo
Crie e execute o exemplo usando as seguintes instruções:
Abra um prompt de comando do Visual Studio ou do .NET Framework.
Se necessário, crie um diretório para o exemplo. Para este exemplo, usaremos C:\MySample.
Em c:\MySample, crie
HelloWorld.vb(para o exemplo do Visual Basic) ouHelloWorld.cs(para o exemplo de C#) e copie o código de exemplo do Visual Basic ou C# apropriado (abaixo) no arquivo.Em c:\MySample, crie o arquivo
messages.resxe copie o código de exemplo para o arquivo.Em c:\MySample, crie o arquivo
messages.de.resxsalvando o arquivomessages.resxcomomessages.de.resxdepois de alterar a linha<value xml:space="preserve">Hello, World!</value>Para ler
<value xml:space="preserve">Hallo Welt!</value>
Em c:\MySample, crie o arquivo
messages.es.resxsalvando o arquivomessages.resxcomomessages.es.resxdepois de alterar a linha<value xml:space="preserve">Hello, World!</value>Para ler
<value xml:space="preserve">Hola a todos</value>
Em c:\MySample, crie o arquivo
messages.fr.resxsalvando o arquivomessages.resxcomomessages.fr.resxdepois de alterar a linha<value xml:space="preserve">Hello, World!</value>Para ler
<value xml:space="preserve">Bonjour !</value>
Em c:\MySample, crie o arquivo
messages.fr-FR.resxsalvando o arquivomessages.resxcomomessages.fr-FR.resxdepois de alterar a linha<value xml:space="preserve">Hello, World!</value>Para ler
<value xml:space="preserve">Bonjour de France!</value>
Em c:\MySample, crie o arquivo
messages.it.resxsalvando o arquivomessages.resxcomomessages.it.resxdepois de alterar a linha<value xml:space="preserve">Hello, World!</value>Para ler
<value xml:space="preserve">Buongiorno</value>
Em c:\MySample, crie o arquivo
messages.ja.resxsalvando o arquivomessages.resxcomomessages.ja.resxdepois de alterar a linha<value xml:space="preserve">Hello, World!</value>Para ler
<value xml:space="preserve">ã"ã‚"ã«ã¡ã¯</value>
Em c:\MySample, crie o arquivo
build.come copie o código de exemplo para o arquivoCompile as montagens satélite executando o build de arquivo no prompt de comando.
Compile o código de exemplo do prompt de linha de comando executando o seguinte:
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.
Se o exemplo estiver instalado em outro diretório, edite
C:\MySample\o arquivoInstall.sqlconforme indicado para apontar para esse local.Implantar o assembly e o procedimento armazenado executando
sqlcmd -E -I -i install.sql
Copie Transact-SQL script de comando de teste em um arquivo e salve-o como
test.sqlno diretório de exemplo.Executar o script de teste com o comando a seguir
sqlcmd -E -I -i test.sql
Copie o script de limpeza Transact-SQL em um arquivo e salve-o como
cleanup.sqlno diretório de exemplo.Executar o script com o comando a seguir
sqlcmd -E -I -i cleanup.sql
Exemplo de código
Veja a seguir as listagens de código para este exemplo.
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
Isto é build.com, que cria os assemblies satélites.
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
Esse é o Transact-SQL script de instalação (Install.sql), que implanta os assemblies e cria o procedimento armazenado dentro do banco de dados.
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
Isto é test.sql, que testa o exemplo executando as funções em cada localidade.
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
O Transact-SQL a seguir remove os assemblies e o procedimento armazenado do banco de dados.
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
Consulte Também
Cenários de uso e exemplos para a integração de CLR (Common Language Runtime)