Compartilhar via


Exemplo pronto para o Olá, Mundo

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:

  1. Alterando um arquivo XML (o arquivo .resx ) para a cultura específica no diretório de recursos

  2. Criando o arquivo de recursos da cultura usando resgen

  3. Criando a DLL satélite atualizada para essa cultura

  4. 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', 1

    GO

    RECONFIGURE

    GO

    Observação

    Para habilitar o CLR, você deve ter ALTER SETTINGS permissão de nível de servidor, que é mantida implicitamente por membros das funções de servidor fixas e sysadmin de serveradmin membros.

  • 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:

  1. Abra um prompt de comando do Visual Studio ou do .NET Framework.

  2. Se necessário, crie um diretório para o exemplo. Para este exemplo, usaremos C:\MySample.

  3. Em c:\MySample, crie HelloWorld.vb (para o exemplo do Visual Basic) ou HelloWorld.cs (para o exemplo de C#) e copie o código de exemplo do Visual Basic ou C# apropriado (abaixo) no arquivo.

  4. Em c:\MySample, crie o arquivo messages.resx e copie o código de exemplo para o arquivo.

  5. Em c:\MySample, crie o arquivo messages.de.resx salvando o arquivo messages.resx como messages.de.resx depois de alterar a linha

    • <value xml:space="preserve">Hello, World!</value>

    • Para ler

    • <value xml:space="preserve">Hallo Welt!</value>

  6. Em c:\MySample, crie o arquivo messages.es.resx salvando o arquivo messages.resx como messages.es.resx depois de alterar a linha

    • <value xml:space="preserve">Hello, World!</value>

    • Para ler

    • <value xml:space="preserve">Hola a todos</value>

  7. Em c:\MySample, crie o arquivo messages.fr.resx salvando o arquivo messages.resx como messages.fr.resx depois de alterar a linha

    • <value xml:space="preserve">Hello, World!</value>

    • Para ler

    • <value xml:space="preserve">Bonjour !</value>

  8. Em c:\MySample, crie o arquivo messages.fr-FR.resx salvando o arquivo messages.resx como messages.fr-FR.resx depois de alterar a linha

    • <value xml:space="preserve">Hello, World!</value>

    • Para ler

    • <value xml:space="preserve">Bonjour de France!</value>

  9. Em c:\MySample, crie o arquivo messages.it.resx salvando o arquivo messages.resx como messages.it.resx depois de alterar a linha

    • <value xml:space="preserve">Hello, World!</value>

    • Para ler

    • <value xml:space="preserve">Buongiorno</value>

  10. Em c:\MySample, crie o arquivo messages.ja.resx salvando o arquivo messages.resx como messages.ja.resx depois de alterar a linha

    • <value xml:space="preserve">Hello, World!</value>

    • Para ler

    • <value xml:space="preserve"> ã"ã‚"にちは</value>

  11. Em c:\MySample, crie o arquivo build.com e copie o código de exemplo para o arquivo

  12. Compile as montagens satélite executando o build de arquivo no prompt de comando.

  13. 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.vb

    • Csc /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.

  14. Se o exemplo estiver instalado em outro diretório, edite C:\MySample\o arquivo Install.sql conforme indicado para apontar para esse local.

  15. Implantar o assembly e o procedimento armazenado executando

    • sqlcmd -E -I -i install.sql
  16. Copie Transact-SQL script de comando de teste em um arquivo e salve-o como test.sql no diretório de exemplo.

  17. Executar o script de teste com o comando a seguir

    • sqlcmd -E -I -i test.sql
  18. Copie o script de limpeza Transact-SQL em um arquivo e salve-o como cleanup.sql no diretório de exemplo.

  19. 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)