AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 115023
Accepted
David Clarke
David Clarke
Asked: 2015-09-15 17:41:50 +0800 CST2015-09-15 17:41:50 +0800 CST 2015-09-15 17:41:50 +0800 CST

Problema com FMTONLY no SQL Server 2012

  • 772

Eu apoio um aplicativo que usa modelos CodeSmith e NetTiers para gerar código C#. CodeSmith inspeciona o banco de dados e usa a SET FMTONLY ONconfiguração para determinar as colunas para as quais o código deve ser gerado.

Infelizmente, ao mudar do SQL Server 2005 para 2012, há uma circunstância específica em que isso não está mais funcionando. Existe um procedimento armazenado que executa um procedimento armazenado em um servidor vinculado e o código que está sendo gerado para esse procedimento armazenado está incorreto.

Consegui isolar o problema da EXECdeclaração com SET FMTONLY ON. O seguinte (somente exemplo) SELECTfunciona nas instâncias de 2005 e 2012:

SET FMTONLY ON
SELECT TOP(10) [MCMCU]
              ,[MCSTYL]
              ,[MCDC]
FROM [JDE].[JDE_CRP].[CRPDTA].[F0006]
SET FMTONLY OFF

Isso retorna apenas os títulos das colunas, conforme esperado. O seguinte funciona apenas na instância de 2005:

SET FMTONLY ON
EXEC('SELECT TOP(10) [MCMCU]
                    ,[MCSTYL]
                    ,[MCDC]
      FROM [JDE_CRP].[CRPDTA].[F0006]') AT [JDE]
SET FMTONLY OFF

Quando executado na instância 2012, o SSMS mostra a mensagem "Comando(s) concluído(s) com êxito", mas não exibe os cabeçalhos das colunas.

Há alguma coisa que estou perdendo aqui? Talvez uma configuração que eu precise alterar? As definições do servidor vinculado são idênticas, incluindo a identidade usada para conectar. E sim, estou ciente de que FMTONLYestá obsoleto, mas não tenho nenhuma capacidade de alterar a maneira como o CodeSmith interroga o banco de dados.

sql-server sql-server-2012
  • 1 1 respostas
  • 1912 Views

1 respostas

  • Voted
  1. Best Answer
    Solomon Rutzky
    2015-09-15T20:14:10+08:002015-09-15T20:14:10+08:00

    Posso reproduzir o mesmo comportamento no SQL Server 2012. No entanto, consigo fazê-lo funcionar colocando o nome do Linked Server de volta na consulta. Existe uma razão para você ter colocado isso na ATcláusula?

    Tente o seguinte:

    SET FMTONLY ON
    EXEC('SELECT TOP(10) [MCMCU]
                        ,[MCSTYL]
                        ,[MCDC]
          FROM [JDE].[JDE_CRP].[CRPDTA].[F0006]');
    SET FMTONLY OFF
    

    Bem, embora o acima funcione no SQL Server 2012, não foi um bom teste porque não funciona ao executar um procedimento armazenado. Pode ter algo a ver com o fato de ser um tipo diferente de chamada (ou seja, a chamada do procedimento armazenado é RPC e teve que ser configurada separadamente).

    Eu até tentei adicionar WITH RESULT SETS ((...))e ainda não funcionou.


    Ok, então eu encontrei algo. É geralmente conhecido que FMTONLY ONna verdade não executa o código, apenas o verifica em busca de SELECTinstruções. Mas isso também significa que ele não sabe como lidar com código condicional. Portanto, ele retorna quaisquer conjuntos de resultados que possam ser retornados, mesmo que nenhum caminho de código retorne alguns deles.

    O exemplo 1 tem duas SELECTinstruções, mas apenas uma pode ser retornada por vez. Ainda assim, ao executar com FMTONLY ON, ambos são retornados:

    CREATE PROCEDURE dbo.FmtOnlyTest1
    AS
    SET NOCOUNT ON;
      DECLARE @A INT = 5;
    
      IF (@A <> 6)
      BEGIN
        SELECT TOP 5 * FROM [master].[sys].[objects];
      END;
      ELSE
      BEGIN
        DECLARE @SQL NVARCHAR(MAX);
        SET @SQL = N'SELECT ' + CONVERT(NVARCHAR(MAX), @A) + N' AS [IntVal];'
        EXEC(@SQL);
    END;
    GO
    

    Resultados:

    -- Running normally returns one result set of 5 rows from sys.objects:
    EXEC Test.dbo.FmtOnlyTest1;
    
    -- With FMTONLY ON, it returns two result sets: one from sys.objects AND one with [IntVal]
    SET FMTONLY ON
    EXEC Test.dbo.FmtOnlyTest1;
    SET FMTONLY OFF
    

    O exemplo 2 mostra outra consequência de não poder executar o código. Se o código produzir o conjunto de resultados dinamicamente, ele não poderá ser determinado por FMTONLY ON. Isso provavelmente explica por que não pode seguir a chamada EXEC quando o código é remoto. Suspeito que chamar procedimentos armazenados locais funcione apenas fazendo uma pesquisa na tabela de catálogo do sistema local para essa definição.

    CREATE PROCEDURE dbo.FmtOnlyTest2
    AS
    SET NOCOUNT ON;
      DECLARE @A INT;
    
      SELECT TOP 1 @A = [object_id] FROM sys.objects;
    
      DECLARE @SQL NVARCHAR(MAX);
      SET @SQL = N'SELECT ' + CONVERT(NVARCHAR(MAX), @A) + N' AS [IntVal];'
      EXEC(@SQL);
    GO
    

    Resultados:

    -- Running normally returns one result set of just [IntVal];
    EXEC Test.dbo.FmtOnlyTest2;
    
    -- With FMTONLY ON, there are no result sets returned (just like with the remote procedure)
    SET FMTONLY ON
    EXEC Test.dbo.FmtOnlyTest2;
    SET FMTONLY OFF
    

    Sabendo o que sabemos agora, podemos usar o fato de que FMTONLY ONencontrará todos os conjuntos de resultados sem realmente executar o código para, mesmo que não seja o ideal, falsificar um conjunto de resultados para fazer o CodeSmith (e outras ferramentas que ainda funcionam dessa maneira) funcionar novamente .

    O exemplo 3 mostra que podemos efetivamente ocultar um conjunto de resultados fictício em um bloco de código que não pode ser executado logicamente. Só FMTONLY ONserá capaz de ver isso para não apresentar um problema para nenhum outro código (bem, eu tentei sys.dm_exec_describe_first_result_sete não gostei muito, mas não acho que seja um problema neste caso).

    CREATE PROCEDURE dbo.FmtOnlyTest3
    AS
    SET NOCOUNT ON;
    
      IF (1 = 0)
      BEGIN
        SELECT CONVERT(INT, NULL) AS [FieldName1],
               CONVERT(DATETIME, NULL) AS [FieldName2];
      END;
    
      DECLARE @A INT;
    
      SELECT TOP 1 @A = [object_id] FROM sys.objects;
    
      DECLARE @SQL NVARCHAR(MAX);
      SET @SQL = N'SELECT ' + CONVERT(NVARCHAR(MAX), @A) + N' AS [IntVal];'
      EXEC(@SQL);
    GO
    

    Resultados:

    -- Running normally returns one result set of just [IntVal];
    EXEC Test.dbo.FmtOnlyTest3;
    
    -- Running with FMTONLY ON returns one result set of [FieldName1], [FieldName2]
    SET FMTONLY ON
    EXEC Test.dbo.FmtOnlyTest3;
    SET FMTONLY OFF
    

    Para este teste, fiz com que o código retornasse um conjunto de resultados diferente para o IF (1 = 0)bloco para tornar a diferença de comportamento mais aparente. Mas, na prática, você gostaria de retornar exatamente a mesma estrutura do conjunto de resultados SELECTcomo retorna o procedimento armazenado remoto.

    A desvantagem óbvia aqui é que, se você alterar o conjunto de resultados desse procedimento remoto, precisará se lembrar de também alterar a definição no IF (1 = 0)bloco, mas pelo menos o CodeSmith funcionará.

    • 5

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve