SQL: Personalizando a instrução de SQL do Recordset (ODBC)
Este tópico explica:
Como a estrutura constrói uma instrução SQL
Como substituir a instrução SQL
Observação |
---|
Essa informação se aplica a classes MFC ODBC.Se você estiver trabalhando com as classes de DAO MFC, consulte o tópico “comparação do mecanismo de banco de dados SQL e ANSI Microsoft SQL Jet” na ajuda de DAO. |
Compilação da instrução SQL
As bases do recordset a seleção primeiro registro em uma instrução SQL SELECIONAR .Quando você declara sua classe com um assistente, grava uma versão substituindo da função de membro de GetDefaultSQL que aspectos mais nada (semelhante para uma classe CAuthorschamado de conjunto de registros).
CString CAuthors::GetDefaultSQL()
{
return "AUTHORS";
}
Por padrão, esta substituição retorna o nome da tabela que você especificou com o assistente.No exemplo, o nome da tabela é “AUTORES”. Quando você posteriormente chamada a função de membro de Abrir do conjunto de registros, Abrir construir uma declaração final de SELECIONAR do formulário:
SELECT rfx-field-list FROM table-name [WHERE m_strFilter]
[ORDER BY m_strSort]
onde table-name é conseguido chamando GetDefaultSQL e rfx-field-list é obtido de chamadas de função de RFX em DoFieldExchange.Este é o que você obtém para uma declaração de SELECIONAR a menos que você substitua pela uma versão de substituição em tempo de execução, embora você também pode modificar a declaração padrão com parâmetros ou um filtro.
Observação |
---|
Se você especificar um nome de coluna que contém (ou) pode conter espaços, você deve incluir o nome de colchetes.Por exemplo, o nome “nome” deve ser “nome” []. |
Para substituir a instrução padrão de SELECIONAR , passe uma cadeia de caracteres que contém uma declaração completa de SELECIONAR quando você chama Abrir.Em vez de criar sua própria cadeia de caracteres padrão, o recordset usa a cadeia de caracteres que você fornece.Se sua declaração de substituição contém uma cláusula WHERE de, não especifique um filtro em m_strFilter porque você teria então duas declarações de filtro.Da mesma forma, se sua declaração de substituição contém uma cláusula de ORDENAR POR , não especifique um tipo em m_strSort para que você não tem duas declarações de tipo.
Observação |
---|
Se você usar cadeias de caracteres literal em seus filtros (ou outras partes da instrução SQL), talvez você precise “citar” (incluir em delimitadores) especificados como cadeias de caracteres com um prefixo literal DBMS- específico e um caractere literal do sufixo ou mais caracteres (). |
Você também pode localizar sintáticos requisitos especiais para operações como externo join, dependendo do seu DBMS.Use funções ODBC para obter esta informação do driver para o DBMS.Por exemplo, ::SQLGetTypeInfo chamada para um tipo de dados específico, como SQL_VARCHAR, para solicitar os caracteres de LITERAL_PREFIX e de LITERAL_SUFFIX .Se você estiver escrevendo código banco de dados independente, consulte apêndice c na referência de programadorODBC SDK no CD da Biblioteca MSDN para informações detalhadas de sintaxe.
Um objeto do recordset constrói a instrução SQL que usa para selecionar registros a menos que você passe uma instrução SQL personalizada.Como isso é feito principalmente depende do valor que você passa para o parâmetro de lpszSQL da função de membro de Abrir .
O formulário geral de uma instrução SQL SELECIONAR é:
SELECT [ALL | DISTINCT] column-list FROM table-list
[WHERE search-condition][ORDER BY column-list [ASC | DESC]]
Uma maneira para adicionar a palavra-chave de DISTINCT à instrução SQL do conjunto de registros é inserir a palavra-chave na primeira chamada de função de RFX em DoFieldExchange.Por exemplo:
...
RFX_Text(pFX, "DISTINCT CourseID", m_strCourseID);
...
Observação |
---|
Use essa técnica somente com um recordset aberto como somente leitura. |
Substituindo a instrução SQL
A tabela a seguir mostra as possibilidades para o parâmetro de lpszSQL a Abrir.Os casos na tabela são explicados após a tabela.
O parâmetro de lpszSQL e a cadeia de caracteres resultante SQL
Case |
O que você passou em lpszSQL |
A instrução SELECT resultante |
---|---|---|
1 |
NULO |
com nomede FROMde rfx-campo- lista deSELECIONAR CRecordset::Open chama GetDefaultSQL para obter o nome da tabela.A cadeia de caracteres resultante é um dos casos 2 a 5, dependendo de GetDefaultSQL retorna. |
2 |
Um nome de tabela |
com nomede FROMde rfx-campo- lista deSELECIONAR A lista de campos é necessária instruções de RFX em DoFieldExchange.Se m_strFilter e m_strSort não estiverem vazias, adiciona as cláusulas de WHERE e/ou de ORDENAR POR . |
3 * |
Uma declaração completa de SELECIONAR mas sem uma cláusula WHERE de ou de ORDENAR POR |
Como passado.Se m_strFilter e m_strSort não estiverem vazias, adiciona as cláusulas de WHERE e/ou de ORDENAR POR . |
4 * |
Uma declaração completa de SELECIONAR com uma cláusula WHERE de e/ou de ORDENAR POR |
Como passado.m_strFilter e/ou m_strSort devem permanecer vazios, ou dois filtrar e/ou as declarações de tipo são geradas. |
5 * |
Uma chamada a um procedimento armazenado |
Como passado. |
* m_nFields deve ser menor ou igual ao número de colunas especificadas na declaração de SELECIONAR .O tipo de dados de cada coluna especificada na declaração de SELECIONAR deve ser o mesmo que o tipo de dados da coluna correspondente de saída de RFX.
LpszSQL dos casos 1 = NULL
A seleção do recordset depende de qual GetDefaultSQL retorna quando CRecordset::Open o chama.Os casos 2 a 5 descrevem as cadeias de caracteres possíveis.
LpszSQL dos casos 2 = um nome de tabela
A troca do campo do registro dos usos do conjunto de registros (RFX) para criar a lista de colunas dos nomes de coluna fornecidos em chamadas de função de RFX na substituição da classe do conjunto de registros de DoFieldExchange.Se você usou um assistente para declarar a classe do conjunto de registros, esses casos têm o mesmo resultado que os casos 1 (desde que você passa o mesmo nome da tabela que você especificou no assistente).Se você não usar um assistente para escrever sua classe, os casos 2 é a maneira mais simples para construir a instrução SQL.
O exemplo a seguir constrói uma instrução SQL que selecionar registros de um banco de dados de aplicativo MFC.Quando a estrutura chama a função de membro de GetDefaultSQL , a função retorna o nome da tabela, SECTION.
CString CEnrollSet::GetDefaultSQL()
{
return "SECTION";
}
Para obter os nomes das colunas para a instrução SQL SELECIONAR , a estrutura chama a função de membro de DoFieldExchange .
void CEnrollSet::DoFieldExchange(CFieldExchange* pFX)
{
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX, "CourseID", m_strCourseID);
RFX_Text(pFX, "InstructorID", m_strInstructorID);
RFX_Text(pFX, "RoomNo", m_strRoomNo);
RFX_Text(pFX, "Schedule", m_strSchedule);
RFX_Text(pFX, "SectionNo", m_strSectionNo);
}
Quando completo, a instrução SQL ele tem a seguinte aparência:
SELECT CourseID, InstructorID, RoomNo, Schedule, SectionNo
FROM SECTION
LpszSQL dos casos 3 = uma instrução de SELECT/FROM
Você especifica a lista de colunas à mão em vez de depender em RFX para construir-lo automaticamente.Você pode querer fazer isso quando:
Você deseja especificar a palavra-chave de DISTINCT depois de SELECIONAR.
A lista de colunas deve corresponder aos nomes de coluna e na mesma ordem que são listados em DoFieldExchange.
Você tem razão para recuperar valores de coluna manualmente usando a função ::SQLGetData ODBC em vez de depender em RFX para associar e recuperar colunas para você.
Você pode desejar, por exemplo, para acomodar novos colunas um cliente do seu aplicativo adicionado nas tabelas de banco de dados após o aplicativo foi distribuído.Você precisa adicionar esses membros adicionais de dados de campo, que não foram conhecidos que o momento você declarou a classe com um assistente.
A lista de colunas deve corresponder aos nomes de coluna e na mesma ordem que são listados em DoFieldExchange, seguido pelos nomes das colunas manualmente associadas.Para obter mais informações, consulte Recordset: Dinamicamente vinculação colunas de dados (ODBC).
Você deseja juntar tabelas especificando várias tabelas na cláusula FROM de.
Para informações e um exemplo, consulte Recordset: Executar uma junção (ODBC).
Case o lpszSQL 4 = o SELECT/FROM mais WHERE e/ou ORDEM PERTO
Você especifica todas: a lista de colunas (com base em chamadas de RFX em DoFieldExchange), a lista da tabela, e o conteúdo de WHERE e/ou de uma cláusula de ORDENAR POR .Se você especificar as cláusulas de WHERE e/ou de ORDENAR POR essa forma, não use m_strFilter e/ou m_strSort.
LpszSQL dos casos 5 = uma chamada de procedimento armazenado
Se você precisar chamar uma consulta predefinida (como um procedimento armazenado em um banco de dados Microsoft SQL Server), você deve escrever uma instrução de CALL na cadeia de caracteres que você passa a lpszSQL.Os assistentes não suportam declarar uma classe de conjunto de registros para chamar uma consulta pré-definida.Nem todos os registros predefinidos de retorno de consultas.
Se uma consulta predefinida não retorna registros, você pode usar a função de membro ExecuteSQL de CDatabase diretamente.Para uma consulta predefinida que retorna registros, você também deve manualmente escrevendo em chamadas de RFX em DoFieldExchange para todas as colunas o procedimento retorna.Chamadas de RFX devem estar na mesma ordem e retornar os mesmos tipos, como a consulta pré-definida.Para obter mais informações, consulte Recordset: Declarando uma classe para uma consulta predefinida (ODBC).