Consultas distribuídas do Microsoft SQL Server: conectividade OLE DB

Este artigo descreve como o processador de consultas do Microsoft SQL Server interage com um provedor OLE DB para habilitar consultas distribuídas e heterogêneas. Ele destina-se principalmente aos desenvolvedores do provedor OLE DB e pressupõe uma compreensão sólida da especificação OLE DB. A ênfase está na interface OLE DB entre o processador de consultas do SQL Server e o provedor OLE DB, não na funcionalidade de consulta distribuída em si. Para obter uma descrição completa da funcionalidade de consulta distribuída, consulte Servidores vinculados (Mecanismo de Banco de Dados).

Visão geral e terminologia

No Microsoft SQL Server, as consultas distribuídas permitem que os usuários do SQL Server acessem dados fora de um servidor baseado no SQL Server, seja em outros servidores que executam o SQL Server ou outras fontes de dados que expõem uma interface OLE DB. O OLE DB fornece uma maneira de acessar uniformemente os dados de tabela de fontes de dados heterogêneos.

Uma consulta distribuída, para fins deste artigo, é qualquer instrução SELECT, INSERT, UPDATE ou DELETE que referencie tabelas e conjuntos de linhas de uma ou mais fontes de dados OLE DB externas.

Uma tabela remota é uma tabela que é armazenada em uma fonte de dados OLE DB e é externa ao servidor que executa o SQL Server que realiza a consulta. Uma consulta distribuída acessa uma ou mais tabelas remotas.

Categorias de provedor OLE DB

A lista a seguir é uma categorização de provedores OLE DB com base em seus recursos do ponto de vista de consulta distribuída do SQL Server. Conforme definido, eles não são mutuamente exclusivos; um determinado provedor pode pertencer a mais de uma das seguintes categorias:

Provedores de comandos SQL

Os provedores que dão suporte ao Command objeto com um dialeto padrão SQL reconhecido pelo SQL Server pertencem a essa categoria. Os requisitos específicos para que determinado provedor OLE DB seja tratado como um provedor de comando SQL pelo SQL Server são:

  • O provedor precisa dar suporte ao objeto Command e a todas as suas interfaces OLE DB obrigatórias: ICommand, ICommandText, IColumnsInfo, ICommandProperties e IAccessor.

  • O dialeto SQL com suporte do provedor precisa ser, pelo menos, Submínimo SQL. O dialeto precisa ser relatado pelo provedor por meio da propriedade DBPROP_SQLSUPPORT.

Exemplos de provedores de comando SQL são o Provedor Microsoft OLE DB para SQL Server e o Provedor Microsoft OLE DB para ODBC.

Provedores de índice

Os provedores de índice são aqueles que dão suporte a índices e os expõem de acordo com o OLE DB e permitem a pesquisa baseada em índice de tabelas base. Os requisitos específicos para que determinado provedor OLE DB seja tratado como um provedor de índice pelo SQL Server são:

  • O provedor deve dar suporte à IDBSchemaRowset interface com os COLUMNSTABLESconjuntos de linhas e INDEXES esquema.

  • O provedor precisa dar suporte à abertura de um conjunto de linhas em um índice por meio de IOpenRowset especificando o nome do índice e o nome da tabela base correspondente.

  • O objeto Index precisa dar suporte a todas as suas interfaces obrigatórias: IRowset, IRowsetIndex, IAccessor, IColumnsInfo, IRowsetInfo e IConvertTypes.

  • Os conjuntos de linhas abertos na tabela base indexada (por meio de IOpenRowset) precisam dar suporte à interface IRowsetLocate para posicionamento em uma linha com base em um indicador.

Se o provedor OLE DB atender aos requisitos anteriores, os usuários poderão definir a opção de Index As Access Path provedor para permitir que o SQL Server use os índices do provedor para avaliar consultas. Por padrão, o SQL Server não tenta usar os índices do provedor, a menos que essa opção esteja definida.

Observação

O SQL Server dá suporte a várias opções que influenciam como o SQL Server acessa um provedor OLE DB. A caixa de diálogo Linked Server Properties do SQL Server Enterprise Manager pode ser usada para definir essas opções.

Provedores de tabela simples

Esses são provedores que expõem a abertura de um conjunto de linhas em uma tabela base por meio da interface IOpenRowset. Esses provedores não são provedores de comando sql nem provedores de índice; em vez disso, eles são a classe mais simples de provedores com os quais as consultas distribuídas do SQL Server podem trabalhar.

Nesses provedores, o SQL Server só pode executar verificações de tabela durante a avaliação da consulta distribuída.

Provedores de comandos não SQL

Provedores que dão suporte ao Command objeto e suas interfaces obrigatórias, mas não dão suporte a um dialeto padrão SQL reconhecido pelo SQL Server, se enquadram nessa categoria.

Dois exemplos de provedores de comando não SQL são o Provedor Microsoft OLE DB para serviço de indexação e o Provedor OLE DB da Microsoft para o serviço Microsoft Active Directory.

subconjunto Transact-SQL

Haverá suporte para cada uma das classes de instruções Transact-SQL a seguir em consultas distribuídas se o provedor der suporte às interfaces OLE DB necessárias.

  • Todas as SELECT instruções são permitidas, exceto para SELECT INTO instruções com uma tabela remota como a tabela de destino.

  • As instruções INSERT são permitidas em tabelas remotas se o provedor dá suporte às interfaces necessárias para inserção. Para obter mais informações sobre os requisitos do OLE DB, INSERTconsulte a instrução INSERT mais adiante neste artigo.

  • UPDATE e DELETE instruções serão permitidas em tabelas remotas se o provedor atender aos requisitos de interface OLE DB na tabela especificada. Para obter os requisitos e condições da interface OLE DB nas quais uma tabela remota pode ser atualizada ou excluída, consulte as instruções UPDATE e DELETE mais adiante neste artigo.

Suporte ao cursor

Haverá suporte para cursores de instantâneo e conjunto de chaves em consultas distribuídas se o provedor der suporte à funcionalidade OLE DB necessária. Não há suporte para cursores dinâmicos em consultas distribuídas. É feito o downgrade para um cursor de conjunto de chaves de uma solicitação de usuário de um cursor dinâmico em uma consulta distribuída.

Os cursores de instantâneo são preenchidos no tempo de abertura do cursor e o conjunto de resultados permanece inalterado; atualizações, inserções e exclusões para as tabelas subjacentes não são refletidas no cursor.

Os cursores de conjunto de chaves são populados durante a abertura do cursor e o conjunto de resultados permanece inalterado durante todo o tempo de vida do cursor. No entanto, as atualizações e as exclusões em tabelas subjacentes são visíveis no cursor conforme as linhas são visitadas. As inserções em tabelas subjacentes que podem afetar a associação ao cursor não estão visíveis.

Uma tabela remota pode ser atualizada ou excluída por meio de um cursor definido em uma consulta distribuída e referencia a tabela remota se o provedor atender às condições de atualizações e exclusões na tabela remota, por exemplo, tabela UPDATE ou DELETE <remote-table> WHERE CURRENT OF <cursor-name>. Para obter mais informações, consulte as instruções UPDATE e DELETE mais adiante neste artigo.

Requisitos de suporte ao cursor de conjunto de chaves

Haverá suporte para um cursor de conjunto de chaves em uma consulta distribuída se todos os requisitos da sintaxe Transact-SQL forem atendidos e um dos seguintes existir:

  • O provedor OLE DB dá suporte a indicadores reutilizáveis em todas as tabelas remotas na consulta. Os indicadores reutilizáveis podem ser consumidos de um conjunto de linhas em determinada tabela e usados em um conjunto de linhas diferente da mesma tabela. O suporte para indicadores reutilizáveis é indicado por meio do TABLES_INFO conjunto de linhas de esquema de IDBSchemaRowset definindo a BOOKMARK_DURABILITY coluna BMK_DURABILITY_INTRANSACTION como ou uma durabilidade mais alta.

  • Todas as tabelas remotas expõem uma chave exclusiva por meio do INDEXES conjunto de linhas da IDBSchemaRowset interface. Deve haver uma entrada de índice com a UNIQUE coluna definida como VARIANT_TRUE.

Não há suporte para cursores de conjunto de chaves em consultas distribuídas que envolvam a função OpenQuery .

Requisitos de cursor de conjunto de chaves atualizáveis

Uma tabela remota pode ser atualizada ou excluída por meio de um cursor de conjunto de chaves definido em uma consulta distribuída, por exemplo, UPDATE ou DELETE <remote-table> WHERE CURRENT OF <cursor-name>. As seguintes são as condições sob as quais cursores atualizáveis em relação a consultas distribuídas são permitidos:

  • Os cursores atualizáveis são permitidos se o provedor também atende às condições de atualizações e exclusões na tabela remota. Para obter mais informações, consulte as instruções UPDATE e DELETE mais adiante neste artigo.

  • Todas as operações atualizáveis do cursor de conjunto de chaves precisam estar em uma transação definida pelo usuário com um nível de isolamento de leitura repetida ou um nível de isolamento mais alto. Além disso, o provedor precisa dar suporte a transações distribuídas com a interface ITransactionJoin.

Fases de interação do provedor OLE DB

Seis operações são comuns a todos os cenários de execução de consulta distribuída:

  • As operações de estabelecimento da conexão e recuperação de propriedade indicam como o SQL Server se conecta a um provedor OLE DB e quais propriedades do provedor são usadas.

  • A resolução de nomes de tabela e as operações de recuperação de metadados indicam como o SQL Server resolve o nome da tabela remota (que é especificado de duas maneiras: um nome baseado em servidor vinculado ou um nome ad hoc) no objeto de dados apropriado no provedor. Isso também inclui os metadados de tabela que o SQL Server recupera do provedor para compilar e otimizar uma consulta distribuída.

  • As operações de gerenciamento de transações especificam toda a interação relacionada à transação com o provedor OLE DB.

  • As operações de tratamento de tipo de dados indicam como os tipos de dados OLE DB são tratados pelo SQL Server quando ele consome dados de um provedor OLE DB ou exporta dados para ele durante o processamento de uma consulta distribuída.

  • As operações de tratamento de erro indicam como o SQL Server usa as informações de erro estendido do provedor.

  • As operações de segurança especificam como a segurança do SQL Server interage com a segurança do provedor.

Estabelecimento de conexão e recuperação de propriedade

O SQL Server dá suporte a duas convenções de nomenclatura de objeto de dados remoto: nomes de quatro partes baseados no servidor vinculado e nomes ad hoc que usam a função OPENROWSET.

Nomes baseados no servidor vinculado

Um servidor vinculado serve como uma abstração para uma fonte de dados OLE DB. Um nome baseado no servidor vinculado é um nome de quatro partes do formato <linked-server>.<catalog>. <schema>.<object>, em que <linked-server> é o nome do servidor vinculado. O SQL Server interpreta <linked-server> para derivar o provedor OLE DB e os atributos de conexão que identificam a fonte de dados para o provedor. As outras três partes do nome são interpretadas pela fonte de dados OLE DB para identificar a tabela remota específica. :::

Nomes ad hoc

Um nome ad hoc é um nome baseado na função OPENROWSET ou OPENDATASOURCE. Ele inclui todas as informações de conexão (ou seja, o provedor OLE DB a ser usado, os atributos necessários para identificar a fonte de dados, a ID de usuário e a senha) sempre que a tabela remota é referenciada em uma consulta distribuída.

O uso de nomes ad hoc não é permitido por padrão, exceto para membros da função sysadmin. Para usar nomes ad hoc em um provedor OLE DB, a opção DisallowAdhocAccess do provedor deve ser definida como 0.

Se um nome de servidor vinculado for usado, o SQL Server extrairá da definição de servidor vinculado o nome do provedor OLE DB e as propriedades de inicialização para o provedor. Se um nome ad hoc for usado, o SQL Server extrairá as mesmas informações dos argumentos da função OPENROWSET.

Para obter instruções detalhadas sobre como configurar um servidor vinculado usando um nome de quatro partes e uma sintaxe baseada em nome ad hoc, consulte Criar servidores vinculados (Mecanismo de Banco de Dados do SQL Server).

Conectar-se a um provedor OLE DB

Estas são as etapas de alto nível executadas pelo SQL Server ao se conectar a um provedor OLE DB:

  1. O SQL Server cria um objeto de fonte de dados.

    O SQL Server usa a ProgID do provedor para criar uma instância de seu DSO (objeto de fonte de dados). A ProgID é especificada como o parâmetro provider_name de uma configuração de servidor vinculado ou como o primeiro argumento da função OPENROWSET no caso de um nome ad hoc.

    O SQL Server cria uma instância do DSO do provedor por meio da interface IDataInitialize do componente de serviço OLE DB. Isso permite que o Gerenciador de Componente de Serviço agregue seus serviços, como suporte à atualização e rolagem, acima da funcionalidade nativa do provedor. Além disso, a criação de uma instância do provedor por meio do IDataInitialize permite que o componente de serviço OLE DB agrupe conexões com o provedor, reduzindo uma parte da sobrecarga de conexão e inicialização.

    Um provedor especificado pode ser configurado para ter uma instância criada no mesmo processo do SQL Server ou em seu próprio processo. A criação de uma instância em um processo separado protege o processo do SQL Server contra falhas no provedor. Ao mesmo tempo, há uma sobrecarga de desempenho associada ao marshaling de chamadas OLE DB fora de processo do SQL Server. Um provedor pode ser configurado para ter uma instância criada em processo ou fora do processo pela definição da opção Allow In Process do provedor. Para obter mais informações, confira Como definir as opções do provedor.

    Para saber mais sobre os componentes de serviço do OLE DB e o pooling de sessões, confira a documentação do OLE DB para obter os requisitos do provedor.

  2. A fonte de dados é inicializada.

    Depois que o DSO tiver sido criado, a IDBProperties interface definirá a DBPROP_INIT_TIMEOUT propriedade de inicialização se a opção remote login timeout de configuração do servidor for maior que 0; essa é uma propriedade necessária.

    Essas propriedades serão definidas se forem especificadas ou implícitas na definição do servidor vinculado ou no segundo argumento da OPENROWSET função:

    • DBPROP_INIT_PROVIDERSTRING
    • DBPROP_INIT_DATASOURCE
    • DBPROP_INIT_LOCATION
    • DBPROP_INIT_CATALOG
    • DBPROP_AUTH_USERID
    • DBPROP_AUTH_PASSWORD

    Depois que essas propriedades forem definidas, IDBInitialize::Initialize será chamado para inicializar o DSO com as propriedades especificadas.

  3. O SQL Server coleta informações específicas do provedor.

    O SQL Server coleta várias propriedades do provedor a serem usadas na avaliação de consulta distribuída; essas propriedades são recuperadas com uma chamada a IDBProperties::GetProperties. Todas essas propriedades são opcionais; no entanto, o suporte a todas as propriedades relevantes permite que o SQL Server aproveite ao máximo as funcionalidades do provedor. Por exemplo, DBPROP_SQLSUPPORT é necessário para determinar se o SQL Server pode enviar consultas ao provedor. Se essa propriedade não tiver suporte, o SQL Server não usará o provedor remoto como um Provedor de Comandos SQL, mesmo que seja uma. Na tabela a seguir, a coluna de valor padrão indica qual valor o SQL Server pressupõe se o provedor não der suporte à propriedade.

    Propriedade Valor padrão Usar
    DBPROP_DBMSNAME Nenhum Usado para mensagens de erro.
    DBPROP_DBMSVER Nenhum Usado para mensagens de erro.
    DBPROP_PROVIDERNAME Nenhum Usado para mensagens de erro.
    DBPROP_PROVIDEROLEDBVER1 1.5 Usado para determinar a disponibilidade dos recursos do 2.0.
    DBPROP_CONCATNULLBEHAVIOR Nenhum Usado para determinar se o comportamento da concatenação de NULL do provedor é o mesmo que o do SQL Server.
    DBPROP_NULLCOLLATION Nenhum Permite a classificação/o uso do índice somente se NULLCOLLATION corresponde ao comportamento de ordenação de nulo da Instância do SQL Server.
    DBPROP_OLEOBJECTS Nenhum Determina se o provedor dá suporte a interfaces de armazenamento estruturado para colunas de objeto de dados grandes.
    DBPROP_STRUCTUREDSTORAGE Nenhum Determina quais interfaces de armazenamento estruturado são compatíveis com tipos de objeto grande (entre ILockBytes, Istream e ISequentialStream).
    DBPROP_MULTIPLESTORAGEOBJECTS Falso Determina se mais de uma coluna de objeto grande pode ser aberta ao mesmo tempo.
    DBPROP_SQLSUPPORT Nenhum Determina se as consultas SQL podem ser enviadas ao provedor.
    DBPROP_CATALOGLOCATION DBPROPVAL_CL_START Usado para construir nomes de tabela com várias partes.
    SQLPROP_DYNAMICSQL Falso Propriedade específica do SQL Server: se ela retornar VARIANT_TRUE, indicará que os marcadores de parâmetro ? são compatíveis com a execução de consulta parametrizada.
    SQLPROP_NESTEDQUERIES Falso Propriedade específica do SQL Server: se ela retornar VARIANT_TRUE, indicará que o provedor dá suporte a instruções SELECT aninhadas na cláusula FROM.
    SQLPROP_GROUPBY Falso Propriedade específica do SQL Server: se retorna VARIANT_TRUE, indica que o provedor dá suporte GROUP BY à SELECT cláusula na instrução, conforme especificado pelo padrão SQL-92.
    SQLPROP_DATELITERALS Falso Propriedade específica do SQL Server: se ela retornar VARIANT_TRUE, indicará que o provedor dá suporte a literais de datetime de acordo com a sintaxe Transact-SQL do SQL Server.
    SQLPROP_ANSILIKE Falso Propriedade específica do SQL Server: essa propriedade é de interesse de um provedor que dá suporte ao nível Mínimo do SQL e dá suporte ao operador LIKE de acordo com o nível entrada da SQL-92 ('%' e '_' como caracteres curinga).
    SQLPROP_SUBQUERIES Falso Propriedade do SQL Server: essa propriedade é de interesse de um provedor que dá suporte ao nível Mínimo SQL. Essa propriedade indica que o provedor dá suporte a subconsultas, conforme especificado pelo nível Entrada da SQL-92. Isso inclui as subconsultas na lista SELECT e na cláusula WHERE com suporte para subconsultas correlacionadas e os operadores IN, EXISTS, ALL e ANY.
    SQLPROP_INNERJOIN Falso Propriedade do SQL Server: essa propriedade é de interesse para provedores que dão suporte ao nível Mínimo SQL. Essa propriedade indica suporte para junções usando várias tabelas na cláusula FROM.

    Os três literais a seguir são recuperados de : IDBInfo::GetLiteralInfo, DBLITERAL_CATALOG_SEPARATOR (para construir um nome de objeto completo de acordo com suas partes de catálogo, esquema e nome de objeto) e DBLITERAL_SCHEMA_SEPARATOR (para citar nomes de DBLITERAL_QUOTEidentificador em uma consulta SQL enviada ao provedor).

    Se o provedor não der suporte aos literais separadores, o SQL Server usará um período (.) como o caractere separador padrão. Se o provedor der suporte apenas ao caractere separador de catálogo, mas não ao caractere separador de esquema, o SQL Server usará o caractere separador de catálogo como o caractere separador de esquema também. Se o provedor não der suporte DBLITERAL_QUOTE, o SQL Server usará uma única aspa (') como o caractere de aspas.

    Observação

    Se os literais do separador de nomes do provedor não corresponderem a esses valores padrão, o provedor deverá expô-los IDBInfo para que o SQL Server acesse suas tabelas por meio de nomes de quatro partes. Se esses literais não forem expostos, somente consultas de passagem poderão ser usadas em relação a esse provedor.

Para obter informações sobre como expor as propriedades SQLPROP_DYNAMICSQL e SQLPROP_NESTEDQUERIES, confira Propriedades específicas do SQL Server.

Resolução de nomes de tabela e recuperação de metadados

O SQL Server resolve um nome de tabela remota especificado em uma consulta distribuída para uma tabela ou uma exibição específica em uma fonte de dados OLE DB. Ambos os esquemas de nomenclatura ad hoc e de servidor vinculado resultam em um nome de três partes a ser interpretado pelo provedor. No caso do nome baseado no servidor vinculado, as últimas três partes do nome de quatro partes formam os nomes de catálogo, esquema e objeto. No caso do nome ad hoc, o terceiro argumento da função OPENROWSET especifica um nome de três partes que descreve os nomes de catálogo, esquema e objeto. Um ou ambos os nomes de catálogo e esquema podem estar vazios. (Um nome de quatro partes com um nome de catálogo vazio e um nome de esquema seria semelhante a <server-name>...<object-name>.) Nesse caso, o SQL Server usa NULL como o valor correspondente a ser procurado nas tabelas de conjunto de linhas de esquema.

As regras de resolução de nomes e as etapas de recuperação de metadados que o SQL Server emprega dependem se o provedor dá suporte à IDBSchemaRowset interface no Session objeto.

Se houver suporte para IDBSchemaRowset, os conjuntos de linhas de esquema TABLES, COLUMNS, INDEXES e TABLES_INFO serão usados da interface IDBSchemaRowset. (O conjunto de linhas de esquema TABLES_INFO é definido no OLE DB 2.0) O SQL Server restringe os conjuntos de linhas de esquema retornados pela interface IDBSchemaRowset para procurar as colunas de esquema que correspondem às partes de nome da tabela remota especificadas. Veja a seguir as regras relacionadas às restrições com suporte do provedor nos conjuntos de linhas de esquema e como o SQL Server as usa para recuperar os metadados de uma tabela remota:

  • As restrições nas colunas TABLE_NAME e COLUMN_NAME são sempre necessárias.

  • Se o provedor der suporte a uma restrição TABLE_CATALOG (ou TABLE_SCHEMA), o SQL Server usará essa restrição em TABLE_CATALOG (ou TABLE_SCHEMA). Se o nome do catálogo (ou esquema) não for especificado no nome da tabela remota, um NULL valor será usado como o valor de restrição correspondente. Se um nome de catálogo (ou esquema) for especificado, o provedor precisará dar suporte à restrição correspondente em TABLE_CATALOG (ou TABLE_SCHEMA).

  • O provedor precisa dar suporte à restrição na coluna TABLE_SCHEMA em TABLES e COLUMNS ou dar suporte a eles em nenhuma delas. O provedor precisa dar suporte à restrição de nome de catálogo nos conjuntos de linhas TABLES ou COLUMNS ou dar suporte a eles em nenhum deles.

  • Se houver suporte INDEXESpara restrições, o provedor deverá dar suporte à restrição de esquema em ambos TABLES e INDEXES ou dar suporte a elas em nenhum dos dois. O provedor precisa dar suporte à restrição de nome de catálogo nos conjuntos de linhas TABLES ou INDEXES ou dar suporte a eles em nenhum deles.

No conjunto de linhas de esquema, o TABLES SQL Server recupera as TABLE_CATALOGcolunas, TABLE_SCHEMAdefinindo TABLE_NAMETABLE_TYPETABLE_GUID restrições de acordo com as regras anteriores.

No conjunto de linhas de esquema COLUMNS, o SQL Server recupera as colunas TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, COLUMN_GUID, ORDINAL_POSITION, COLUMN_FLAGS, IS_NULLABLE, DATA_TYPE, TYPE_GUID, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION e NUMERIC_SCALE. COLUMN_NAME, DATA_TYPEe ORDINAL_POSITION deve retornar valores não nulos válidos. Se DATA_TYPE for DBTYPE_NUMERIC ou DBTYPE_DECIMAL, o NUMERIC_PRECISION e NUMERIC_SCALE correspondentes precisarão ser valores não nulos válidos.

No conjunto de linhas de esquema INDEXES opcional, o SQL Server procura índices na tabela remota especificada definindo as restrições de acordo com as regras anteriores. Nas entradas de índice correspondentes assim encontradas, o SQL Server recupera as colunas TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, INDEX_CATALOG, INDEX_SCHEMA, INDEX_NAME, PRIMARY_KEY, UNIQUE, CLUSTERED, FILL_FACTOR, ORDINAL_POSITION, COLUMN_NAME, COLLATION, CARDINALITY e PAGES.

No conjunto de linhas opcional TABLES_INFO , o SQL Server procura informações adicionais sobre a tabela remota especificada, como suporte a indicadores, o tipo e o comprimento do indicador. Todas as colunas, exceto a coluna DESCRIPTION do conjunto de linhas TABLES_INFO, são usadas. As informações do conjunto de linhas TABLES_INFO são usadas da seguinte maneira:

  • A coluna BOOKMARK_DURABILITY é usada para implementar cursores de conjunto de chaves mais eficientes. Se essa coluna tiver um valor igual a BMK_DURABILITY_INTRANSACTION ou um valor de durabilidade mais alto, o SQL Server usará a recuperação baseada em indicador e as atualizações de linhas da tabela remota para implementar um cursor de conjunto de chaves.

  • As BOOKMARK_TYPEcolunas e BOOKMARK_MAXIMUM_LENGTH o indicador BOOKMARK_DATA_TYPEsão usados para determinar metadados de indicador no momento da compilação da consulta. Se essas colunas não tiverem suporte, o SQL Server abrirá o conjunto de linhas IOpenRowset da tabela base durante a compilação para obter as informações do indicador.

Se IDBSchemaRowset não houver suporte e o nome da tabela remota incluir um nome de catálogo ou esquema, o SQL Server exigirá IDBSchemaRowset e retornará um erro. No entanto, se o catálogo ou os nomes de esquema não forem fornecidos, o SQL Server abrirá o conjunto de linhas que corresponde à tabela remota e recuperará os metadados de coluna da interface obrigatória IColumnsInfo do objeto rowset.

O SQL Server abre o conjunto de linhas correspondente à tabela chamando IOpenRowset::OpenRowset. O nome da tabela fornecido para OPENROWSET é construído com base nas partes do nome de objeto, catálogo e esquema.

  • Cada uma das partes do nome (catalog, schema e object name) é colocada entre aspas com o caractere de aspas do provedor (DBLITERAL_QUOTE) e, em seguida, concatenada com o caractere DBLITERAL_CATALOG_SEPARATOR e o caractere DBLITERAL_SCHEMA_SEPARATOR inserido entre eles. A construção de nome segue as regras do OLE DB em IOpenRowset.

  • Os metadados de coluna da tabela são recuperados IColumnsInfo::GetColumnInfo depois que o objeto rowset é aberto.

Se IDBSchemaRowset não houver suporte para TABLESconjuntos de linhas e TABLES_INFO , COLUMNSo SQL Server abrirá o conjunto de linhas na tabela base duas vezes: uma vez durante a compilação da consulta para recuperar metadados e uma vez durante a execução da consulta. Os provedores que geram efeitos colaterais por abrir o conjunto de linhas (por exemplo, executar um código que altera o estado de um dispositivo em tempo real, enviar emails, executar um código arbitrário fornecido pelo usuário) precisam estar cientes desse comportamento.

Recuperação de estatísticas

Se o provedor der suporte a estatísticas de distribuição nas tabelas base, o SQL Server usará essas estatísticas. Há dois tipos de estatísticas de interesse para o processador de consultas do SQL Server:

  • Cardinalidades de coluna (ou tupla). Esse é o número de valores exclusivos que estão em uma coluna (ou uma combinação de colunas) de uma tabela. Isso pode ser usado para estimar a seletividade de predicados em relação às colunas. Um provedor que dá suporte a estatísticas de distribuição deve dar suporte a, pelo menos, um tipo de cardinalidade.

  • Histogramas. Se a distribuição de valores não for uniforme, o não. de valores exclusivos não é suficiente para estimar com precisão a seletividade dos predicados. Nesse caso, é possível fornecer um histograma que fornece informações mais refinadas sobre a distribuição de valores de coluna em uma tabela.

A disponibilidade de estatísticas permite que o otimizador de consulta do SQL Server especifique melhor as cardinalidades de operações intermediárias em uma consulta, o que permite que ele gere planos de execução melhores para elas.

O provedor OLE DB deve dar suporte a estatísticas de distribuição da seguinte maneira:

  • Obrigatório. Dê suporte às propriedades (1), DBPROP_TABLESTATISTICSque indica se há suporte para cardinalidades de coluna ou tupla e se há suporte para histogramas e (2), DBPROP_OPENROWSETSUPPORTo que indica o uso do DBPROPVAL_ORS_HISTOGRAM bit, se há suporte para histogramas.

  • Obrigatório. O conjunto de linhas de esquema TABLE_STATISTICS. O conjunto de linhas de esquema TABLE_STATISTICS lista as estatísticas disponíveis em determinado banco de dados. Ele também inclui as cardinalidades de coluna e tupla no próprio conjunto de linhas de esquema e indica se há suporte para histogramas nas colunas específicas. Para que o SQL Server use estatísticas, as colunas TABLE_NAME, STATISTICS_NAME, STATISTICS_TYPE, COLUMN_NAME e ORDINAL_POSITION são obrigatórias nesse conjunto de linhas de esquema. Pelo menos um COLUMN_CARDINALITY ou TUPLE_CARDINALITY é obrigatório. Se houver suporte para histogramas, também NO_OF_RANGES será obrigatório.

  • Opcional. Opcionalmente, se o provedor der suporte a histogramas, ele deverá dar suporte a uma melhoria para o método IOpenRowset::OpenRowset, que permite abrir um conjunto de linhas de histograma especificando o DBID da estatística correspondente.

Para obter informações completas sobre as interfaces de estatísticas, confira a especificação OLE DB 2.6.

Restrições

O otimizador de consulta do SQL Server também usa as restrições CHECK definidas nas tabelas base em uma fonte de dados remota se o provedor OLE DB dá suporte ao conjunto de linhas de esquema CHECK_CONSTRAINTS_BY_TABLE do OLE DB 2.6. A coluna CHECK_CLAUSE do conjunto de linhas de esquema deve retornar o predicado de cláusula CHECK na sintaxe em conformidade com a SQL-92. O otimizador de consulta usa informações de restrição para eliminar ou simplificar predicados que são sempre falsos ou sempre verdadeiros devido à presença de uma restrição de verificação na tabela.

Gerenciamento de transações

O SQL Server dá suporte ao acesso baseado em transação a dados distribuídos usando as interfaces OLE DB ITransactionLocal (para transação local) e ITransactionJoin (para transações distribuídas) do provedor. Ao iniciar uma transação local no provedor, o SQL Server garante operações de gravação atômicas. Ao usar transações distribuídas, o SQL Server garante que uma transação que envolva vários nós tenha o mesmo resultado (confirmação ou anulação) em todos os nós. Se o provedor não der suporte às interfaces relacionadas à transação OLE DB necessárias, as operações de atualização nesse provedor não serão permitidas dependendo do contexto da transação local.

A tabela a seguir descreve o que acontece quando o usuário executa uma consulta distribuída, considerando as funcionalidades do provedor e um contexto de transação local. Uma operação de leitura em um provedor refere-se a uma instrução SELECT ou quando a tabela remota é lida no lado de entrada de uma instrução SELECT INTO, INSERT, UPDATE ou DELETE. Uma operação de gravação em um provedor refere-se a uma instrução INSERT, UPDATE ou DELETE com uma tabela remota como a tabela de destino.

Os resultados de uma consulta distribuída com base nas funcionalidades do provedor e no contexto da transação:

A consulta distribuída ocorre O provedor não dá suporte ITransactionLocal O provedor dá suporte a ITransactionLocal, mas não a ITransactionJoin O provedor dá suporte a ITransactionLocal e ITransactionJoin
Em uma transação por si só (sem transação de usuário). Por padrão, somente operações de leitura são permitidas. Quando a opção Nontransacted Updates do nível de provedor está habilitada, as operações de gravação são permitidas. (Quando essa opção está habilitada, o SQL Server não pode garantir atomicidade e consistência nos dados do provedor. Isso pode fazer com que os efeitos parciais de uma operação de gravação sejam refletidos na fonte de dados remota sem a capacidade de desfazê-los.) Todas as instruções são permitidas em dados remotos. Os cursores de conjunto de chaves são somente leitura. A transação local é iniciada no provedor com o nível de isolamento da sessão atual do SQL Server e é confirmada no final de uma avaliação de instrução bem-sucedida. (O nível de isolamento padrão para uma sessão do SQL Server é READ COMMITTED , a menos que seja modificado com a instrução SET TRANSACTION ISOLATION LEVEL . O provedor deve dar suporte ao nível de isolamento solicitado.) Todas as instruções são permitidas. Os cursores de conjunto de chaves são somente leitura. A transação local é iniciada no provedor com o nível de isolamento da sessão atual do SQL Server e é confirmada no final de uma avaliação de instrução bem-sucedida.
Em uma transação de usuário (ou seja, entre BEGIN TRAN ou BEGIN DISTRIBUTED TRAN e COMMIT). Se o nível de isolamento da transação for READ COMMITTED (o padrão) ou abaixo, as operações de leitura serão permitidas. Se o nível de isolamento for maior, nenhuma consulta distribuída será permitida. Somente operações de leitura são permitidas. Novas transações distribuídas são iniciadas no provedor com o nível de isolamento da sessão atual do SQL Server. Todas as instruções são permitidas. A nova transação distribuída é iniciada no provedor com o nível de isolamento da sessão atual do SQL Server e confirmada quando a transação de usuário é confirmada. Para instruções de modificação de dados, por padrão, o SQL Server inicia uma transação aninhada abaixo da transação distribuída, para que a instrução de modificação de dados possa ser interrompida em determinadas condições de erro sem interromper a transação adjacente. Se a opção estiver ativada, o XACT_ABORT SET SQL Server não exigirá suporte a transações aninhadas e interromperá a transação ao redor no caso de erros durante a instrução de modificação de dados.

Tratamento de tipo de dados em consultas distribuídas

Os provedores OLE DB expõem seus dados em termos dos tipos de dados definidos pelo OLE DB (indicado por DBTYPE no OLE DB). O SQL Server processa dados externos dentro do servidor como tipos nativos do SQL Server; isso resulta em um mapeamento de tipos de dados OLE DB para tipos nativos do SQL Server e vice-versa, pois os dados são consumidos pelo SQL Server ou exportados pelo SQL Server, respectivamente. Esse mapeamento é feito implicitamente, salvo indicação em contrário.

Os tipos de dados em consultas distribuídas são tratados usando um dos dois métodos de mapeamento:

  • O mapeamento do lado do consumo mapeia tipos de tipos de dados OLE DB para tipos de dados nativos do SQL Server no lado consumidor, quando tabelas remotas aparecem em SELECT instruções e no lado de entrada de INSERT, UPDATEe DELETE instruções.

  • O mapeamento do lado da exportação mapeia os tipos dos tipos de dados do SQL Server para tipos de dados OLE DB no lado da exportação, quando uma tabela remota aparece como a tabela de destino de uma instrução INSERT ou UPDATE.

Tabela de mapeamento de tipo de dados do SQL Server e OLE DB.

Tipo OLE DB DBCOLUMNFLAG Tipo de dados do SQL Server
DBTYPE_I1 1 numeric(3, 0)
DBTYPE_I2 smallint
DBTYPE_I4 int
DBTYPE_I8 numeric(19,0)
DBTYPE_UI1 tinyint
DBTYPE_UI2 1 numeric(5,0)
DBTYPE_UI4 1 numeric(10,0)
DBTYPE_UI8 1 numeric(20,0)
DBTYPE_R4 float
DBTYPE_R8 real
DBTYPE_NUMERIC numeric
DBTYPE_DECIMAL decimal
DBTYPE_CY money
DBTYPE_BSTR DBCOLUMNFLAGS_ISFIXEDLENGTH=true
ou
Comprimento > máximo de 4.000 caracteres
ntext
DBTYPE_BSTR DBCOLUMNFLAGS_ISFIXEDLENGTH=true nchar
DBTYPE_BSTR DBCOLUMNFLAGS_ISFIXEDLENGTH=false nvarchar
DBTYPE_IDISPATCH Erro
DBTYPE_ERROR Erro
DBTYPE_BOOL bit
DBTYPE_VARIANT 1 nvarchar
DBTYPE_IUNKNOWN Erro
DBTYPE_GUID uniqueidentifier
DBTYPE_BYTES DBCOLUMNFLAGS_ISLONG=true
ou
Comprimento > máximo de 8.000
image
DBTYPE_BYTES DBCOLUMNFLAGS_ISROWVER=true, DBCOLUMNFLAGS_ISFIXEDLENGTH=truetamanho da coluna = 8
ou
Tamanho máx. não relatado.
timestamp
DBTYPE_BYTES DBCOLUMNFLAGS_ISFIXEDLENGTH=true binário
DBTYPE_BYTES DBCOLUMNFLAGS_ISFIXEDLENGTH=true varbinary
DBTYPE_STR DBCOLUMNFLAGS_ISFIXEDLENGTH=true queimar
DBTYPE_STR DBCOLUMNFLAGS_ISFIXEDLENGTH=true varchar
DBTYPE_STR DBCOLUMNFLAGS_ISLONG=true
ou
Comprimento > máximo de 8.000 caracteres
ou
Tamanho máx. não relatado.
Texto
DBTYPE_WSTR DBCOLUMNFLAGS_ISFIXEDLENGTH=true nchar
DBTYPE_WSTR DBCOLUMNFLAGS_ISFIXEDLENGTH=false nvarchar
DBTYPE_WSTR DBCOLUMNFLAGS_ISLONG=true
ou
Comprimento >máximo de 4.000 caracteres
ou
Tamanho máx. não relatado.
ntext
DBTYPE_UDT Erro
DBTYPE_DATE datetime
DBTYPE_DBDATE 1 datetime (conversão explícita necessária)
DBTYPE_DBTIME datetime (conversão explícita necessária)
DBTYPE_DBTIMESTAMP 1 datetime
DBTYPE_ARRAY Erro
DBTYPE_BYREF Ignorado
DBTYPE_VECTOR Erro
DBTYPE_RESERVED Erro

1 Indique alguma forma de tradução para a representação do tipo SQL Server, pois não há nenhum tipo de dados equivalente exato no SQL Server. Essas conversões podem resultar em perda de precisão, estouro ou estouro negativo. Os mapeamentos implícitos padrão poderão ser alterados no futuro se houver suporte para os tipos de dados correspondentes em versões futuras do SQL Server.

Observação

numeric(p,s) indica o tipo de dados numeric do SQL Server com precisão p e escala s. A precisão máxima permitida para DBTYPE_NUMERIC e DBTYPE_DECIMAL é 38. O provedor precisa dar suporte à associação à coluna DBTYPE_BSTR como DBTYPE_WSTR durante a criação de um acessador. DBTYPE_VARIANT as colunas são consumidas como cadeias de caracteres Unicode nvarchar. Isso exige suporte para conversão de DBTYPE_VARIANT para DBTYPE_WSTR do provedor. O provedor deve implementar essa conversão conforme definido no OLE DB. Para obter mais informações, confira Tipos de dados da especificação OLE DB.

Interpretar o mapeamento de tipo de dados

O mapeamento para um tipo do SQL Server é determinado pelo tipo de dados OLE DB e pelos DBCOLUMNFLAGS valores que descrevem a coluna ou o valor escalar. No caso do conjunto de linhas de esquema COLUMNS, as colunas DATA_TYPE e COLUMN_FLAGS representam esses valores. No caso da interface IColumnsInfo::GetColumnInfo, os membros wType e dwFlags da estrutura DBCOLUMNINFO representam essas informações.

Para usar o mapeamento do lado de consumo para determinada coluna com um valor DBTYPE e DBCOLUMNFLAG específico, procure o tipo do SQL Server correspondente na tabela. As regras de tipo para colunas de tabelas remotas em expressões podem ser descritas pela seguinte regra simples:

Um valor especificado de coluna remota é válido em uma expressão Transact-SQL se o tipo do SQL Server mapeado correspondente na tabela é válido no mesmo contexto.

A tabela e a regra definem:

  • Comparações e expressões.

Em geral, X <op> <remote-column> é uma expressão válida se <op> é um operador válido no tipo de dados de X e no tipo de dados para o qual <remote-column> é mapeado.

  • Conversões explícitas.

Convert(X, <remote-column>)é permitido se o DBTYPE tipo Y de dados nativo de <remote-column> mapas (de acordo com a tabela anterior) e a conversão explícita de Y para é X permitida.

Se os usuários desejarem que os dados remotos sejam convertidos em um tipo de dados nativo não padrão, eles precisarão usar uma conversão explícita.

Para usar o mapeamento do lado de exportação no caso de instruções UPDATE e INSERT em tabelas remotas, mapeie os tipos de dados nativos do SQL Server para tipos de dados OLE DB usando a mesma tabela. Um mapeamento de um tipo S1 do SQL Server para determinado tipo OLE DB T será permitido se um dos seguintes existir:

  • O mapeamento correspondente pode ser encontrado na tabela de mapeamento diretamente.

  • Há uma conversão implícita permitida de outro tipo S2 do S1 SQL Server, de modo que S2 mapeia para digitar T na tabela de mapeamento.

Tratamento de LOB (objeto grande)

Conforme indicado na tabela de mapeamento, se as colunas do tipo DBTYPE_STR, DBTYPE_WSTRou DBTYPE_BSTR também relatarem DBCOLUMNFLAGS_ISLONG, ou se o comprimento máximo exceder 4.000 caracteres (ou se nenhum comprimento máximo for relatado), o SQL Server as tratará como um texto ou coluna ntext conforme apropriado. Da mesma forma, para DBTYPE_BYTES colunas, se DBCOLUMNFLAGS_ISLONG for definido ou se o comprimento máximo for maior que 8.000 bytes (ou se o comprimento máximo não for relatado), as colunas serão tratadas como colunas de imagem . colunas de texto, ntext e imagem são chamadas de colunas LOB.

O SQL Server não expõe a funcionalidade completa de texto e imagem em LOBs de um provedor OLE DB. TEXTPTRS não há suporte para objetos grandes de um provedor OLE DB; portanto, nenhuma das funcionalidades relacionadas tem suporte, por exemplo, a função do TEXTPTR sistema e READTEXT, WRITETEXTe UPDATETEXT instruções. SELECT instruções que recuperam colunas LOBs inteiras têm suporte, assim como instruções UPDATE e INSERT para colunas inteiras de grandes objetos em tabelas remotas.

O SQL Server usará as interfaces de armazenamento estruturado em colunas LOB se o provedor der suporte a elas. As interfaces de armazenamento estruturado em ordem crescente de preferência e as funcionalidades são as seguintes: ISequentialStream, Istream ou ILockBytes. Se houver suporte para uma ou mais dessas interfaces, o provedor deverá retornar DBPROPVAL_OO_BLOB como o valor da DBPROP_OLEOBJECTS propriedade quando for consultado por meio da IDBProperties interface. Além disso, o provedor deve indicar suporte para as interfaces às quais ele dá suporte na propriedade DBPROP_STRUCTUREDSTORAGE.

Se o provedor não der suporte a nenhuma das interfaces de armazenamento estruturadas em colunas LOB, o SQL Server materializará essa interface por conta própria e ainda as exporá como colunas de texto, ntext ou imagem .

Acessar colunas LOB

Se o provedor der suporte a uma das interfaces de armazenamento estruturado, o SQL Server executará as seguintes etapas para recuperar colunas LOB durante a execução da consulta:

  1. Antes de abrir o conjunto de linhas por meio de IOpenRowset::OpenRowset, o SQL Server solicitará suporte para uma ou mais das interfaces de armazenamento estruturado (ISequentialStream, Istream e ILockBytes) nas colunas de objeto grande. A primeira interface com suporte do provedor é necessária; interfaces adicionais são solicitadas como "set if cheap" definindo o elemento dwOptions da estrutura correspondente DBPROP como DBPROPOPTIONS_SETIFCHEAP. Por exemplo, se um provedor der suporte a ISequentialStream e ILockBytes, ISequentialStream será obrigatório e ILockBytes será solicitado como "set if cheap".

  2. Depois que o conjunto de linhas é aberto, o SQL Server usa IRowsetInfo::GetProperties para identificar as interfaces reais disponíveis no conjunto de linhas. A última interface ou a interface mais preferencial que o provedor retornou é usada. Quando o SQL Server cria um acessador na coluna de objeto grande, a coluna é associada como DBTYPE_IUNKNOWN com o elemento iid da DBOBJECT estrutura no conjunto de associação para a interface.

Ler de colunas LOB

Use o ponteiro de interface para a interface de armazenamento estruturado solicitada retornada no buffer de linha de IRowset::GetData para fazer a leitura da coluna de objeto grande. Se o provedor não der suporte a várias LOBs abertas ao mesmo tempo (ou seja, se não der suporte DBPROP_MULTIPLE_STORAGEOBJECTS) e se a linha tiver várias colunas de objeto grandes, o SQL Server copiará as colunas LOB em uma tabela de trabalho local.

UPDATE e INSERT instruções em colunas LOB

O SQL Server passa para o provedor um ponteiro para um novo objeto de armazenamento, em vez de usar a interface fornecida pelo provedor para modificar o objeto de armazenamento. Para cada coluna LOB, o valor que é atualizado ou inserido em um objeto de armazenamento é criado com a interface de armazenamento estruturado escolhida. Dependendo se é uma UPDATE operação ou INSERT uma operação, um ponteiro para o objeto de armazenamento é passado para o provedor por meio IRowsetChange::SetData ou IRowsetChange::InsertRow, respectivamente.

Tratamento de erros

Quando uma invocação de método específica em um provedor OLE DB retorna um código de erro, o SQL Server procura as informações de erro estendido do provedor antes de retornar informações sobre a condição de erro para o usuário.

O SQL Server usa o objeto de erro do OLE DB, conforme especificado pelo OLE DB. Algumas das etapas de alto nível são:

  1. Quando uma invocação de método retorna um código de erro do provedor, o SQL Server procura a interface ISupportErrorInfo. Se houver suporte para essa interface, o SQL Server chamará ISupportErrorInfo::InterfaceSupportsErrorInfo para verificar se há suporte para os objetos de erro pela interface que produziu o código de erro.

  2. Se houver suporte para objetos de erro na interface, o SQL Server chamará a função GetErrorInfo para obter um ponteiro de interface IErrorInfo no objeto de erro atual.

  3. O SQL Server usa a interface IErrorInfo para obter um ponteiro para a interface IErrorRecords.

  4. O SQL Server usa IErrorRecords para executar um loop em todos os registros de erro no objeto e obter o texto da mensagem de erro correspondente a cada registro.

Para obter mais informações sobre como o objeto de erro do provedor é usado, confira a documentação do OLE DB.

Segurança

Quando um consumidor se conecta a um provedor OLE DB, o provedor geralmente exige uma ID de usuário e uma senha, a menos que o consumidor deseje ser autenticado como um usuário de segurança integrada. No caso de consultas distribuídas, o SQL Server funciona como o consumidor do provedor OLE DB em nome do logon do SQL Server que executa a consulta distribuída. O SQL Server mapeia o logon atual do SQL Server para uma ID de usuário e uma senha no servidor vinculado.

Esses mapeamentos podem ser especificados pelo usuário para determinado servidor vinculado e podem ser configurados e gerenciados pelos procedimentos armazenados do sistema sp_addlinkedsrvlogin e sp_droplinkedsrvlogin. Ao definir as propriedades do grupo de inicialização DBPROP_AUTH_USERID e DBPROP_AUTH_PASSWORD por meio de IDBProperties::SetProperties, a ID de usuário e a senha determinados pelo mapeamento são passados para o provedor durante o estabelecimento da conexão.

Quando um cliente se conectar ao SQL Server por meio da Autenticação do Windows e se o logon tiver uma configuração de mapeamento self usando sp_addlinkedsrvlogin, o SQL Server tentará representar o contexto de segurança do cliente e definirá a propriedade DBPROP_AUTH_INTEGRATED no provedor durante o estabelecimento da conexão. Esse processo é chamado de delegação.

Depois que o contexto de segurança usado para a conexão for determinado, a autenticação desse contexto de segurança e a verificação de permissão para esse contexto em relação aos objetos de dados na fonte de dados ficam inteiramente sob a responsabilidade do provedor OLE DB.

Para obter mais informações, consulte sp_addlinkedserver e sp_droplinkedsrvlogin.

Cenários de execução de consulta

Ao avaliar uma consulta distribuída, o SQL Server interage com o provedor OLE DB em um ou mais destes cenários:

Consulta remota

O SQL Server gera uma consulta SQL que avalia uma parte da consulta original que pode ser avaliada em sua totalidade pelo provedor. Esse cenário só é possível em provedores de comando SQL. A extensão em que o SQL Server envia operações para o provedor gerando uma consulta SQL depende da gramática SQL compatível com o provedor. O provedor deve indicar seu nível de suporte ao SQL por meio do seguinte:

  1. Indicando o suporte de nível Entrada da SQL-92, Núcleo ODBC ou SQL Mínimo por meio da propriedade DBPROP_SQLSUPPORT. O nível de sintaxe SQL Mínimo é um novo nível compatível com o SQL Server que permite ao SQL Server enviar consultas remotas para provedores simples que dão suporte a um subconjunto simples do SQL. Esse nível abrange uma instrução básica SELECT que não inclui subconsultas, várias tabelas na FROM cláusula (portanto, nenhuma junção) e GROUP BY. Para que o subconjunto da gramática SQL que é usado pelo SQL Server gere consultas remotas nos provedores de cada um desses níveis de sintaxe, confira Subconjunto SQL usado para gerar consultas remotas.

  2. Ao dar suporte a várias propriedades específicas do SQL Server para indicar suporte para recursos individuais do SQL que não estão incluídos de outra forma no nível de sintaxe, conforme relatado por DBPROP_SQLSUPPORT. A lista de propriedades e como elas são usadas pelo SQL Server são descritas posteriormente nesta seção.

O SQL Server usa a execução de consulta parametrizada com um ponto de interrogação (?) como o marcador de parâmetro na cadeia de caracteres Transact-SQL. A execução de consulta parametrizada é usada nos provedores OLE DB do SQL Server, do Microsoft Jet e do Oracle. Em relação a outros provedores, a execução de consulta parametrizada será usada se o provedor der ICommandWithParameters suporte ao Command objeto e pelo menos uma das seguintes condições for atendida:

  • O provedor indica o nível de suporte Núcleo ODBC do SQL Server por meio da propriedade DBPROP_SQLSUPPORT.

  • O provedor indica suporte para o marcador de parâmetro de ponto de interrogação (?) dando suporte à propriedade específica do SQLPROP_DYNCMICSQL SQL Server por meio de IDBPProperties. Para obter mais informações, confira a próxima seção sobre propriedades do provedor.

  • O administrador define a opção Dynamic Parameters do provedor no provedor para fazer com que o SQL Server gere consultas parametrizadas.

Quando o SQL Server gera o texto SQL a ser executado remotamente, os nomes de tabela e coluna são colocados entre aspas com o caractere de aspas do provedor, conforme relatado por meio do literal DBLITERAL_QUOTE da interface IDBInfo. Se esse literal não tiver suporte, os nomes de tabela e coluna não serão citados.

Se o provedor der suporte à execução de consulta parametrizada, o SQL Server considerará uma estratégia de execução de consulta parametrizada avaliar uma junção de uma tabela remota com uma tabela local. A consulta parametrizada é executada repetidamente para valores de parâmetro gerados de cada linha da tabela local. Essa estratégia reduz o número de linhas recuperadas do provedor e é benéfica quando uma tabela local com algumas linhas é unida a uma tabela remota com um grande número de linhas. Essa estratégia de junção remota pode ser imposta pela dica do otimizador de junção REMOTE. Para obter mais informações sobre a execução de consulta parametrizada, confira Como executar consultas parametrizadas:

Veja a seguir as etapas de nível superior no provedor no cenário de consulta remota.

  1. O SQL Server cria um objeto Command com base no objeto Session usando IDBCreateCommand::CreateCommand.

  2. Se a opção de configuração do servidor Remote Query Timeout for definida com um valor > 0, o SQL Server definirá a propriedade DBPROP_COMMANDTIMEOUT no objeto Command com o mesmo valor usando ICommandProperties::SetProperties. ICommand::SetCommandText precisa ser chamado para definir o texto de comando para a cadeia de caracteres Transact-SQL gerada.

  3. O SQL Server chama ICommandPrepare::Prepare para preparar o comando. Se o provedor não der suporte a essa interface, o SQL Server continuará com a Etapa 4.

  4. Se a consulta gerada for parametrizada, o SQL Server usará ICommandWithParameters::SetParameterInfo para descrever os parâmetros e IAccessor::CreateAccessor para criar acessadores para os parâmetros.

  5. O SQL Server chama ICommand::Execute para executar o comando e criar o conjunto de linhas.

  6. O SQL Server usa a interface IRowset para navegar pelas linhas da tabela e consumi-las. Use IRowset::GetNextRows para efetuar fetch de linhas, IRowset::RestartPosition para reposicionar o início do conjunto de linhas e IRowset::ReleaseRows para liberar linhas.

Propriedades de interesse do provedor para execução de consulta remota

Se o provedor der suporte a recursos SQL que não são cobertos pelo nível de sintaxe relatado DBPROP_SQLSUPPORT, ele poderá indique-os usando várias propriedades específicas do provedor.

  • SQLPROP_GROUPBY. Essa propriedade é de interesse de um provedor que dá suporte ao nível Mínimo SQL. Essa propriedade indica que o provedor dá suporte às GROUP BY cláusulas e HAVING à SELECT instrução. Além disso, essa propriedade também indica que o provedor dá suporte às cinco funções MINde agregação a seguir, MAX, e SUMCOUNTAVG. O provedor pode não dar suporte DISTINCT ao argumento dessas funções de agregação.

  • SQLPROP_SUBQUERIES. Essa propriedade é de interesse de um provedor que dá suporte ao nível Mínimo SQL. Ela indica que o provedor dá suporte a subconsultas, conforme especificado pelo nível Entrada da SQL-92. Isso inclui as subconsultas na lista SELECT e na cláusula WHERE com suporte para subconsultas correlacionadas e os operadores IN, EXISTS, ALL e ANY.

  • SQLPROP_DATELITERALS. Essa propriedade é de interesse de qualquer provedor (incluindo aqueles que dão suporte ao nível Entrada da SQL-92). O suporte à sintaxe literal padrão para literais datetime não faz parte do nível de entrada do SQL-92. Essa propriedade específica do SQL Server indica que o provedor dá suporte à sintaxe literal datetime, conforme especificado pelo padrão SQL-92.

  • SQLPROP_ANSILIKE. De interesse de um provedor que dá suporte ao nível Mínimo SQL. Essa propriedade indica que o provedor dá suporte ao operador de acordo com o LIKE nível de entrada SQL-92 ('%' e '_' como caracteres curinga). Isso é útil em um provedor que dá suporte ao nível de SQL-Minimum porque o Nível de SQL-Minimum não inclui LIKE suporte.

  • SQLPROP_INNERJOIN. Essa propriedade é de interesse para provedores que dão suporte ao nível Mínimo SQL. Ela indica suporte para várias tabelas na cláusula FROM. Isso é útil em um provedor que dá suporte apenas ao nível de SQL-Minimum porque o nível de SQL-Minimum não inclui suporte para junções. Isso não indica suporte para palavras-chave explícitas JOIN e não indica suporte para OUTER junções. Ele indica suporte apenas a junções implícitas por meio de uma lista de tabelas na cláusula FROM.

  • SQLPROP_DYNAMICSQL. Indica suporte para ? como um marcador de parâmetro. O marcador de parâmetro deve ter suporte no lugar de um item escalar em uma cláusula WHERE ou na lista SELECT. O suporte para ? marcadores de parâmetro permite que o SQL Server envie consultas parametrizadas ao provedor.

  • SQLPROP_NESTEDQUERIES. Indica suporte para aninhados SELECTna FROM cláusula (por exemplo, SELECT * FROM (SELECT * FROM T)). Em muitos casos, o SQL Server usa instruções SELECT aninhadas na cláusula FROM de uma consulta quando ele gera as cadeias de consulta a serem executadas remotamente. Como o suporte aninhado SELECT não é exigido pelo nível de entrada do SQL-92, o SQL Server não delega consultas com instruções aninhadas SELECT ao provedor, a menos que o provedor também defina essa propriedade. Como alternativa, o administrador também pode definir a opção Nested Queries do provedor para o provedor, a fim de fazer com que o SQL Server gere consultas aninhadas no provedor.

O provedor pode dar suporte a essas propriedades usando um conjunto de propriedades específico do SQL Server chamado SQLPROPSET_OPTHINTS e ter valores PROPID definidos. O conjunto de propriedades SQLPROPSET_OPTHINTS e as duas propriedades são definidos usando as seguintes constantes:

extern const GUID SQLPROPSET_OPTHINTS = { 0x2344480c, 0x33a7, 0x11d1, { 0x9b, 0x1a, 0x0, 0x60, 0x8, 0x26, 0x8b, 0x9e } };
enum SQLPROPERTIES {
SQLPROP_NESTEDQUERIES = 0x4,
SQLPROP_DYNAMICSQL = 0x5,
SQLPROP_GROUPBY = 0x6,
SQLPROP_DATELITERALS = 0x7,
SQLPROP_ANSILIKE = 0x8,
SQLPROP_INNERJOIN = 0x9,
SQLPROP_SUBQUERIES = 0x10
};

Implicações do conjunto de caracteres e da ordem de classificação

O SQL Server dá suporte à especificação de uma ordenação para dados de caractere em um nível por coluna. A ordenação inclui o conjunto de caracteres e a especificação da ordem de classificação para dados de caracteres não Unicode (colunas char e varchar ). Para dados Unicode (colunas nchar e nvarchar ), a ordenação especifica apenas a ordem de classificação.

O SQL Server delegará comparações de cadeia de caracteres ao provedor somente se o conjunto de caracteres (para dados não Unicode), a ordem de classificação e a semântica de comparação de cadeia de caracteres usados pelo servidor vinculado forem os mesmos usados pelo servidor local.

No caso de servidores vinculados do SQL Server, o SQL Server determina automaticamente a compatibilidade da ordenação. Para outros provedores, o administrador precisa indicar ao SQL Server a ordenação de dados de caractere de determinado servidor vinculado. No SQL Server, há suporte para uma nova opção de servidor vinculado chamada Collation Name. Se o administrador determinar que a semântica de ordenação adotada pelo servidor vinculado é igual a uma das ordenações SQL Server Standard, ele poderá definir a opção Collation Name para esse nome de ordenação. A opção Collation Name pode ser definida usando o procedimento armazenado do sistema sp_serveroption. Essa opção só deverá ser definida se ambas as condições a seguir forem atendidas:

  • A ordem de classificação remota e o conjunto de caracteres são os mesmos que a ordenação do SQL Server especificada.

  • A semântica de comparação de cadeia de caracteres usada pelo provedor OLE DB segue as especificações do padrão SQL-92 ou, de maneira equivalente, a semântica de comparação do SQL Server.

Ainda há suporte para a opção Compatível com Ordenação no SQL Server 7.0, por motivos de compatibilidade com versões anteriores. Defini-lo como true é equivalente a definir a opção Nome de Ordenação para a ordenação padrão do master banco de dados do SQL Server. Os novos aplicativos devem usar a opção Nome da Ordenação em vez da opção Compatível com Ordenação.

Acesso indexado

O SQL Server usa um índice exposto pelo provedor para avaliar determinados predicados da consulta distribuída. Esse cenário só é possível em provedores de índice e quando o usuário define a opção de provedor Index as Access Path. Estas são as principais etapas de alto nível executadas pelo SQL Server no provedor ao usar um índice para executar uma consulta:

  1. Abre o conjunto de linhas de índice por meio de IOpenRowset::OpenRowset com os nomes completos da tabela e do índice. Os nomes completos de tabela e do índice são gerados conforme descrito anteriormente no cenário de consulta remota.

  2. Abre o conjunto de linhas da tabela base por meio de IOpenRowset::OpenRowset com o nome completo da tabela.

  3. Define intervalos no conjunto de linhas do índice com base no predicado de consulta por meio de IRowsetIndex::SetRange.

  4. Examina as linhas no conjunto de linhas do índice por meio de IRowset no conjunto de linhas do índice.

  5. Usa a coluna de indicadores das linhas de índice recuperadas para efetuar fetch de linhas correspondentes no conjunto de linhas da tabela base por meio de IRowsetLocate::GetRowsByBookmark.

As propriedades do conjunto de linhas DBPROP_IRowsetLocate e DBPROP_BOOKMARKS são necessárias no conjunto de linhas aberto na tabela base.

Verificações de tabela pura

O SQL Server examina toda a tabela remota do provedor e executa toda a avaliação de consulta localmente. O conjunto de linhas correspondente à tabela é aberto pela chamada a IOpenRowset::OpenRowset. O SQL Server constrói o nome da tabela fornecido para OPENROWSET com base nas partes do nome de objeto, catálogo e esquema da seguinte maneira:

  1. Cada uma das partes de nome é citada com o caractere de aspas do provedor (DBLITERAL_QUOTE) e, em seguida, concatenada com o DBLITERAL_CATALOG_SEPARATOR caractere inserido entre elas.

  2. Depois que o objeto rowset é aberto, o SQL Server usa a IColumnsInfo interface para verificar se os metadados em tempo de execução são iguais aos metadados de tempo de compilação para a tabela.

  3. O SQL Server usa a interface IRowset para navegar pelas linhas da tabela e consumi-las. Use IRowset::GetNextRows para efetuar fetch de linhas, IRowset::RestartPosition para reposicionar o início do conjunto de linhas e IRowset::ReleaseRows para liberar linhas.

Instruções UPDATE e DELETE

As seguintes condições precisam ser atendidas para que uma tabela remota seja atualizada ou excluída de uma consulta distribuída do SQL Server:

  • O provedor precisa dar suporte a indicadores no conjunto de linhas aberto por meio de IOpenRowset na tabela que está sendo atualizada ou excluída.

  • O provedor precisa dar suporte às interfaces IRowsetLocate e IRowsetChange no conjunto de linhas aberto por meio de IOpenRowset na tabela que está sendo atualizada ou excluída.

  • A interface IRowsetChange precisa dar suporte aos métodos UPDATE (SetData) e DELETE (DeleteRows).

  • Se o provedor não der suporte ITransactionLocal, UPDATE as DELETE instruções serão permitidas somente se a opção Non-transacted estiver definida para esse provedor e se a instrução não estiver em uma transação de usuário.

  • Se o provedor não der suporteITransactionJoin, uma instrução ou DELETE instrução UPDATE será permitida somente se não estiver em uma transação de usuário.

As seguintes propriedades do conjunto de linhas são necessárias no conjunto de linhas aberto na tabela atualizada: DBPROP_IRowsetLocate, DBPROP_IRowsetChange e DBPROP_BOOKMARKS. A propriedade do conjunto de linhas DBPROP_UPDATABILITY é definida como DBPROPVAL_UP_CHANGE ou DBPROPVAL_UP_DELETE, dependendo se a operação executada é um UPDATE ou um DELETE, respectivamente.

As seguintes etapas de alto nível contra o provedor para processar uma operação UPDATE ou DELETE são executadas:

  1. O SQL Server abre o conjunto de linhas da tabela base por meio da interface IOpenRowset. O SQL Server requer as propriedades mencionadas anteriormente no conjunto de linhas.

  2. O SQL Server determina o conjunto de linhas qualificadas a serem atualizadas ou excluídas.

  3. O SQL Server usa os indicadores para posicionar as linhas qualificadas por meio da interface IRowsetLocate.

  4. Use IRowsetChange::SetData para operações UPDATE ou IRowsetChange::DeleteRows para operações de exclusão para realizar as alterações necessárias nas linhas qualificadas.

Instrução INSERT

As condições para dar suporte às instruções INSERT em uma tabela remota são menos rigorosas do que para UPDATE e DELETE.

  • O provedor precisa dar suporte a IRowsetChange::InsertRow no conjunto de linhas aberto na tabela base que está sendo inserida.

  • Se o provedor não der suporte ITransactionLocal, INSERT as instruções serão permitidas somente se a opção Non-transacted updates estiver definida para esse servidor vinculado e se a instrução não estiver em uma transação de usuário.

  • Se o provedor não der suporte ITransactionJoin, INSERT as instruções serão permitidas somente se não estiverem em uma transação de usuário.

O SQL Server usa IOpenRowset::OpenRowset para abrir um conjunto de linhas na tabela base e chama IRowsetChange::InsertRow para inserir novas linhas no conjunto de linhas base.

Consultas passagem

Esse cenário é semelhante ao cenário na consulta remota, exceto pelo fato de que o texto de comando fornecido ICommand é uma cadeia de caracteres de comando enviada pelo usuário e não é interpretada pelo SQL Server. O SQL Server usa DBGUID_DEFAULT como o identificador de dialeto quando chama ICommandText::SetCommandText. DBGUID_DEFAULT indica que o provedor deve usar seu dialeto padrão. Se esse texto de comando retornar mais de um conjunto de resultados, por exemplo, se o comando invocar um procedimento armazenado que retorna vários conjuntos de resultados, o SQL Server usará apenas o primeiro conjunto de resultados do comando.

Para obter uma lista de todas as interfaces OLE DB usadas pelo SQL Server, confira Interfaces OLE DB consumidas pelo SQL Server.

Conclusão

O Microsoft SQL Server oferece o conjunto mais robusto de ferramentas para acessar dados de fontes de dados heterogêneos. Ao compreender as interfaces OLE DB expostas pelo SQL Server, os desenvolvedores podem exercer um alto grau de controle e sofisticação em consultas distribuídas.

Interfaces OLE DB consumidas pelo SQL Server

A tabela a seguir lista todas as interfaces OLE DB usadas pelo SQL Server. A coluna Obrigatória indica se a interface faz parte da funcionalidade mínima do OLE DB que o SQL Server precisa ou se é opcional. Se uma determinada interface não estiver marcada como necessária, o SQL Server ainda poderá acessar o provedor, mas alguma funcionalidade ou otimização específica do SQL Server não será possível no provedor.

No caso das interfaces opcionais, a coluna Cenários indica um ou mais dos seis cenários que usam a interface especificada. Por exemplo, a IRowsetChange interface em conjuntos de linhas de tabela base é uma interface opcional; essa interface é usada nos UPDATE cenários de instruções e DELETEINSERT instruções. Se essa interface não tiver suporte, UPDATEDELETEas INSERT instruções não poderão ser compatíveis com esse provedor. Algumas das outras interfaces opcionais são marcadas como "desempenho" na coluna Cenários, indicando que a interface resulta em um melhor desempenho geral. Por exemplo, se a interface não tiver suporte, o IDBSchemaRowset SQL Server deverá abrir o conjunto de linhas duas vezes: uma para seus metadados e uma para execução de consulta. Ao dar suporte a IDBSchemaRowset, o desempenho do SQL Server é aprimorado.

Objeto Interfase Obrigatório Comentários Cenários
Objeto de fonte de dados IDBInitialize Sim Inicialize e configure o contexto de dados e segurança.
IDBCreateSession Sim Crie o objeto de sessão de BD.
IDBProperties Sim Obtenha informações sobre os recursos do provedor, defina as propriedades de inicialização, a propriedade necessária: DBPROP_INIT_TIMEOUT.
IDBInfo Não Obtenha o literal de aspas, o catálogo, o nome, a parte, o separador, o caractere e assim por diante. Consulta remota.
Objeto de sessão de BD IDBSchemaRowset Não Obter metadados de tabela/coluna. Conjuntos de linhas necessários TABLES, COLUMNS e PROVIDER_TYPES; outros que são usados, se disponíveis: INDEXES e TABLE_STATISTICS. Desempenho, acesso indexado.
IOpenRowset Sim Abra um conjunto de linhas em uma tabela, índice ou histograma.
IGetDataSource Sim Use-a para retornar ao DSO de um objeto de sessão de BD.
IDBCreateCommand Não Use-a para criar um objeto de comando (consulta) para os provedores que dão suporte à consulta. Consulta remota, consulta passagem.
ITransactionLocal Não Use-a para atualizações transacionadas. Instruções UPDATE, DELETE e INSERT.
ITransactionJoin Não Use-a para o suporte à transação distribuída. Instruções UPDATE, DELETE e INSERT se estiverem em uma transação de usuário.
Objeto de conjunto de linhas IRowset Sim Examine as linhas.
IAccessor Sim Faça uma associação a colunas em um conjunto de linhas.
IColumnsInfo Sim Obtenha informações sobre as colunas de um conjunto de linhas.
IRowsetInfo Sim Obtenha informações sobre as propriedades do conjunto de linhas.
IRowsetLocate Não Necessária para operações UPDATE/DELETE e para fazer pesquisas baseadas em índice; usada para pesquisar linhas por indicadores. Acesso indexado UPDATEe DELETE instruções.
IRowsetChange Não Necessária para INSERTS/UPDATES/ DELETES em um conjunto de linhas. Os conjuntos de linhas em tabelas base devem dar suporte a essa interface para INSERTinstruções e DELETE instruçõesUPDATE. Instruções UPDATE, DELETE e INSERT.
IConvertType Sim Use-a para verificar se o conjunto de linhas dá suporte a conversões de tipo de dados específicos em suas colunas.
Índice IRowset Sim Examine as linhas. Acesso indexado, desempenho.
IAccessor Sim Faça uma associação a colunas em um conjunto de linhas. Acesso indexado, desempenho.
IColumnsInfo Sim Obtenha informações sobre as colunas de um conjunto de linhas. Acesso indexado, desempenho.
IRowsetInfo Sim Obtenha informações sobre as propriedades do conjunto de linhas. Acesso indexado, desempenho.
IRowsetIndex Sim Necessária somente para conjuntos de linhas em um índice; usada para a funcionalidade de indexação (definir intervalo, buscar). Acesso indexado, desempenho.
Comando ICommand Sim Consulta remota, consulta passagem.
ICommandText Sim Use-a para definir o texto da consulta. Consulta remota, consulta passagem.
IColumnsInfo Sim Use para obter metadados de coluna para resultados da consulta. Consulta remota, consulta passagem.
ICommandProperties Sim Use-a para especificar as propriedades necessárias nos conjuntos de linhas retornados pelo comando. Consulta remota, consulta passagem.
ICommandWithParameters Não Use-a para a execução de consulta parametrizada. Consulta remota, desempenho.
ICommandPrepare Não Use para preparar um comando para obter metadados (usados em consultas de passagem, se disponíveis). Consulta remota, desempenho.
Objeto Error IErrorRecords Sim Use-a para obter um ponteiro para uma interface IErrorInfo correspondente a um único registro de erro.
IErrorInfo Sim Use-a para obter um ponteiro para uma interface IErrorInfo correspondente a um único registro de erro.
Qualquer objeto ISupportErrorInfo Não Use-a para verificar se determinada interface dá suporte a objetos de erro.

Observação

O Index objeto, Command o objeto e Error o objeto não são obrigatórios. No entanto, se houver suporte, as interfaces listadas serão obrigatórias conforme especificado na coluna Obrigatório.

Subconjunto SQL usado para gerar consultas remotas

O subconjunto SQL gerado pelo processador de consultas do SQL Server em um provedor de comando SQL depende do nível de sintaxe ao qual o provedor dá suporte, conforme indicado pela propriedade DBPROP_SQLSUPPORT.

Provedores de comando SQL que dão suporte ao nível de entrada SQL ou Núcleo ODBC

O SQL Server usa o seguinte subconjunto da linguagem SQL para consultas avaliadas por provedores de comandos SQL que dão suporte ao nível Entrada da SQL-92 ou Núcleo ODBC:

  1. Instruções SELECT com as cláusulas SELECT, FROM, WHERE, GROUP BY, UNION, UNION ALL, ORDER BY DESC, ASC e HAVING.

  2. UNION e UNION ALL são gerados somente em provedores que dão suporte ao nível Entrada da SQL-92, não naqueles que dão suporte ao Núcleo ODBC.

  3. Cláusula SELECT:

    • Subconsultas escalares na lista SELECT.
    • Aliases de coluna sem a palavra-chave AS.
  4. Cláusula FROM:

    • Palavras-chave de junção explícitas não são usadas; Nomes de tabela separados por vírgulas são usados para especificar junções internas e junções externas não são especificadas em consultas remotas.

    • Consultas aninhadas do formato FROM (<nested query>) <alias>.

    • Aliases de tabela sem a palavra-chave AS.

  5. A cláusula WHERE usa subconsultas com NOTEXISTS, ANY e ALL.

  6. Expressões:

    • Funções de agregação usadas: MIN([DISTINCT]), MAX([DISTINCT]), COUNT([DISTINCT]), SUM([DISTINCT]), AVG([DISTINCT]) e COUNT(*).

    • Operadores de comparação: <, =, <=, >, <>, >=, IS NULL e IS NOT NULL.

    • Operadores boolianos: AND, OR e NOT.

    • Operadores aritméticos: +, -, * e /.

  7. Constantes:

    • Os literais numéricos e monetários são sempre colocados entre ( ).
    • Os literais de caracteres são colocados entre ' '.

Provedores de comandos SQL que dão suporte ao nível SQL Mínimo

Nos provedores de comandos SQL que dão suporte ao nível SQL Mínimo, o SQL Server gera o SQL usando a gramática a seguir.

Essa gramática foi derivada com o uso da gramática de SQL Mínimo descrita no ODBC 3.0. Todas as diferenças dessa gramática são realçadas. Os itens mostrados em *bold italics* são aqueles adicionados à gramática de SQL Mínimo descrita no ODBC 3.0. Os itens mostrados como excluídos em verde são aqueles removidos dessa gramática.

<select_statement> ::=

SELECT [ ALL | DISTINCT ] <select_list> FROM <table_reference_list> [ WHERE <search_condition> ] [ <order_by_clause> ]

SELECT clause

select_list ::= * | <select_sublist> [ , <select_sublist> ] ...

<select_sublist> ::= expression [ <alias> ]

<alias> ::= <user_defined_name>

FROM clause

<table_reference_list> ::= <table_reference>

<table_identifier> ::= <user_defined_name>

<table_name> ::= <table_identifier>

<table_reference> ::= <table_name>

WHERE clause

<search_condition> ::= <boolean_term> [ OR <search_condition> ]

<boolean_term> ::= <boolean_factor> [ AND <boolean_term> ]

<boolean_factor> ::= [ NOT ] <boolean_primary>

<boolean_primary> ::= <comparison_predicate> | ( <search_condition> )

<comparison_predicate> ::= <expression> <comparison_operator expression>
                           | expression IS [ NOT ] NULL

comparison_operator ::= < | > | <= | >= | = | <>

ORDER BY <order_by_clause>

<order_by_clause> ::= ORDER BY <sort_specification> [ , <sort_specification> ] ...

<sort_specification> ::= { | column_name } [ ASC | DESC ]

Elementos sintacticos comuns

<expression> ::= <term> | <expression> { + | - } <term>

<term> ::= <factor> | <term> { * | / } <factor>

<factor> ::= [ + | - ] <primary>

<primary> ::= <column_name>
              | literal
              | ( <expression> )

<column_name> ::= [ <table_name>. ] <column_identifier>

<literal> ::= <character_string_literal>
      | <integer_literal>
      | <exact_numeric_literal>

<character_string_literal> ::= '{<character> }...'

<integer_literal> ::= [ + | - ] <unsigned_integer>

<exact_numeric_literal>::= [ + | - ] <unsigned_integer> [ period <unsigned_integer> ]

<period> <unsigned_integer>

<base_table_name> ::= <base_table_identifier>

<base_table_identifier> ::= <user_defined_name>

<column_identifier> ::= <user_defined_name>

<user_defined_name> ::= letter [ <digit> | letter | _ ] ...

<unsigned_integer> ::= {<digit>}...

<digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

period ::= .

<character> é qualquer caractere no conjunto de caracteres da fonte de dados/driver. Para incluir um único caractere de aspa literal (') em um <character_string_literal>, use dois caracteres de aspa literal ('').

Propriedades específicas do SQL Server

enum SQLPROPERTIES
       {
       SQLPROP_NOHPNEEDED = 0x1,
       SQLPROP_FREETHREADED = 0x2,
       SQLPROP_UMSENABLED = 0x3,
       SQLPROP_NESTEDQUERIES = 0x4,
       SQLPROP_DYNAMICSQL = 0x5,
       SQLPROP_GROUPBY = 0x6,
       SQLPROP_DATELITERALS = 0x7,
       SQLPROP_ANSILIKE = 0x8,
       SQLPROP_INNERJOIN = 0x9,
       SQLPROP_SUBQUERIES = 0x10,
       SQLPROP_PARALLELSCAN = 0x11,
       SQLPROP_COLUMNCOLLATION = 0x12,
       SQLPROP_CARDINALITY = 0x13,
       SQLPROP_SIMPLEUPDATES = 0x14,
       SQLPROP_SQLLIKE = 0x15,
       SQLPROP_BITREMOTING = 0x16,
       SQLPROP_UNICODELITERALS = 0x17,
       SQLPROP_USELATESTCOLLATIONVERSION = 0x18
       };