microsoft for sql database sdk odbc odbc-bridge

for - odbc sql server driver download



Crear un controlador ODBC personalizado (6)

Esta publicación ahora es un poco antigua, pero vale la pena mencionar que si necesita tener un controlador ODBC, puede usar un SDK como este: http://www.simba.com/drivers/simba-engine-sdk/ Cuida de la mayoría de los puntos planteados en las otras respuestas y le ofrece una interfaz mucho más simplificada para implementar.

Yo trabajo para Simba, por lo que soy un poco parcial, pero usar un SDK hace que sea bastante fácil crear un controlador ODBC para lo que sea que intentes hacer. Puedes desarrollar algo en 5 días si eres un poco hábil en la codificación.

Una de las otras publicaciones recomienda unixODBC o iODBC como puntos de partida, sin embargo, esto no funcionará. Es importante darse cuenta de la distinción entre un administrador de controladores (unixODBC, iODBC, etc.) y un controlador. El Administrador de controladores actúa como intermediario entre la aplicación y el controlador, eliminando la necesidad de vincular directamente a un controlador.

Puede comenzar con los controladores Postgres o MySQL como punto de partida y bifurcarlos para usar su propia base de datos, sin embargo, es poco probable que sea una tarea trivial. Crear un controlador desde cero es aún más difícil y es probable que tenga costos de mantenimiento continuos (y más altos de lo esperado). Mientras sea consciente de los costos de este enfoque, también puede ser viable.

En mi trabajo actual, estamos buscando implementar nuestro propio controlador odbc para permitir que muchas aplicaciones diferentes puedan conectarse a nuestra propia aplicación como fuente de datos. En este momento estamos tratando de sopesar las opciones de desarrollo de nuestro propio controlador a la especificación de implementación, que es masiva, o usando un SDK que permite a los programadores ''completar'' las partes específicas de datos y permitir niveles más altos de abstracción.

¿Alguien más ha implementado un controlador odbc personalizado? ¿Qué trampas te encontraste? ¿Qué beneficios viste al hacerlo tú mismo? ¿Cuántas horas hombre te tomaría aproximadamente? ¿Usó un SDK? De ser así, ¿qué beneficios / inconvenientes observó de ese enfoque?

Cualquier comentario y respuesta sería muy apreciado. ¡Gracias!

EDITAR: Estamos tratando de mantener la portabilidad con nuestro código, que está escrito en C.


Los controladores ODBC son muy complejos: la decisión de escribir uno no debe tomarse a la ligera. La revisión de los controladores de código abierto existentes es un buen enfoque para los ejemplos, pero la mayoría tienen fallas que puede que no desee emular :) Las API son las mismas independientemente de la plataforma del sistema operativo. FreeTDS para MSSQL / Sybase tiene una de las mejores implementaciones de código abierto ODBC Driver que he visto.

Si controla la aplicación, puede salirse con la suya implementando lo que podría ser solo un pequeño subconjunto de la especificación en un tiempo razonable. Para usar en un entorno de uso general, puede requerir un esfuerzo bastante mayor para hacerlo bien. Además de simplemente implementar docenas de llamadas contenedoras, también deberás implementar:

  • Funciones de acceso a metadatos
  • Análisis de sintaxis de consultas específicas de ODBC
  • Mapeo de mensajes de error de SQLSTATE
  • Multibyte / conjunto de caracteres de clasificación
  • Soporte de ODBC versión 2,3 - mensajes de error / correlaciones de funciones
  • Cursores
  • UI de configuración de DM para gestionar el origen de datos

No he implementado un controlador ODBC, pero solo quería ofrecer una sugerencia de que puede comenzar con una implementación de código abierto y agregar sus propias personalizaciones. Esto puede hacer que comiences mucho más rápido.

Hay al menos dos opciones:

  • UnixODBC tiene licencia bajo LGPL, lo que significa que si modifica el código, debe realizar modificaciones en código abierto.

  • iODBC tiene licencia bajo LGPL o New BSD, a su elección. El nuevo BSD le permite hacer modificaciones sin hacer sus modificaciones de código abierto.

Sin embargo, no está claro si estos paquetes se ejecutan en Windows, en lugar de ejecutarse en UNIX / Linux con una API cliente consistente con ODBC estándar. No indica qué plataforma está utilizando, por lo que no sé si esto es relevante para usted.


No lo hice, pero una vez me entrevisté en una compañía que había hecho exactamente esto. Hicieron un producto 4GL / DBMS llamado AMPS del mismo tipo de arquitectura que MUMPS, una base de datos jerárquica con 4GL integrado (un género completo de tales sistemas salió durante la década de 1970). Tenían una base de código heredada bastante importante y los clientes que deseaban conectarse utilizando MS Access.

El desarrollador principal que me entrevistó compartió algunas historias de guerra sobre esto. Aparentemente es extremadamente doloroso de hacer y no debe tomarse a la ligera. Sin embargo, realmente lograron implementarlo.

Una alternativa para hacer esto sería proporcionar un producto de mart / BI de datos (a lo largo de las líneas de SAP BW) que presente los datos de su aplicación en una base de datos externa y los masajes en un formato más amigable como un esquema de estrella o copo de nieve.

Esto podría no soportar el acceso en tiempo real, pero podría ser considerablemente más fácil de implementar (y más importante mantener) que un controlador ODBC. Si sus requisitos de acceso en tiempo real son razonablemente predecibles y limitados, podría exponer una API de servicio web para respaldarlos.


Otra opción: en lugar de crear un controlador ODBC, implemente un back-end que explique el protocolo cableado que utiliza otra base de datos (Postgresql o MySQL, por ejemplo).

Sus usuarios pueden luego descargar y usar, por ejemplo, el controlador Postgresql ODBC.

Exactamente qué base de datos de back-end eliges emular probablemente dependa más de qué tan bien esté documentado el formato del protocolo de conexión.

Tanto Postgres como MySQL tienen una documentación decente para sus protocolos cliente-servidor.

Un ejemplo simple de Python 2.7 de un servidor backend que comprende partes del protocolo de cable Postgresql está a continuación. El script de ejemplo crea un servidor que escucha el puerto 9876. Puedo usar el comando psql -h localhost -p 9876 para conectarme al servidor. Cualquier consulta ejecutada devolverá un conjunto de resultados con las columnas abc y def y dos filas, todos los valores NULL.

Leer los documentos de Postgresql y usar algo como wireshark para inspeccionar el tráfico de protocolo real simplificaría la implementación de un back-end compatible con Postgresql.

import SocketServer import struct def char_to_hex(char): retval = hex(ord(char)) if len(retval) == 4: return retval[-2:] else: assert len(retval) == 3 return "0" + retval[-1] def str_to_hex(inputstr): return " ".join(char_to_hex(char) for char in inputstr) class Handler(SocketServer.BaseRequestHandler): def handle(self): print "handle()" self.read_SSLRequest() self.send_to_socket("N") self.read_StartupMessage() self.send_AuthenticationClearText() self.read_PasswordMessage() self.send_AuthenticationOK() self.send_ReadyForQuery() self.read_Query() self.send_queryresult() def send_queryresult(self): fieldnames = [''abc'', ''def''] HEADERFORMAT = "!cih" fields = ''''.join(self.fieldname_msg(name) for name in fieldnames) rdheader = struct.pack(HEADERFORMAT, ''T'', struct.calcsize(HEADERFORMAT) - 1 + len(fields), len(fieldnames)) self.send_to_socket(rdheader + fields) rows = [[1, 2], [3, 4]] DRHEADER = "!cih" for row in rows: dr_data = struct.pack("!ii", -1, -1) dr_header = struct.pack(DRHEADER, ''D'', struct.calcsize(DRHEADER) - 1 + len(dr_data), 2) self.send_to_socket(dr_header + dr_data) self.send_CommandComplete() self.send_ReadyForQuery() def send_CommandComplete(self): HFMT = "!ci" msg = "SELECT 2/x00" self.send_to_socket(struct.pack(HFMT, "C", struct.calcsize(HFMT) - 1 + len(msg)) + msg) def fieldname_msg(self, name): tableid = 0 columnid = 0 datatypeid = 23 datatypesize = 4 typemodifier = -1 format_code = 0 # 0=text 1=binary return name + "/x00" + struct.pack("!ihihih", tableid, columnid, datatypeid, datatypesize, typemodifier, format_code) def read_socket(self): print "Trying recv..." data = self.request.recv(1024) print "Received {} bytes: {}".format(len(data), repr(data)) print "Hex: {}".format(str_to_hex(data)) return data def send_to_socket(self, data): print "Sending {} bytes: {}".format(len(data), repr(data)) print "Hex: {}".format(str_to_hex(data)) return self.request.sendall(data) def read_Query(self): data = self.read_socket() msgident, msglen = struct.unpack("!ci", data[0:5]) assert msgident == "Q" print data[5:] def send_ReadyForQuery(self): self.send_to_socket(struct.pack("!cic", ''Z'', 5, ''I'')) def read_PasswordMessage(self): data = self.read_socket() b, msglen = struct.unpack("!ci", data[0:5]) assert b == "p" print "Password: {}".format(data[5:]) def read_SSLRequest(self): data = self.read_socket() msglen, sslcode = struct.unpack("!ii", data) assert msglen == 8 assert sslcode == 80877103 def read_StartupMessage(self): data = self.read_socket() msglen, protoversion = struct.unpack("!ii", data[0:8]) print "msglen: {}, protoversion: {}".format(msglen, protoversion) assert msglen == len(data) parameters_string = data[8:] print parameters_string.split(''/x00'') def send_AuthenticationOK(self): self.send_to_socket(struct.pack("!cii", ''R'', 8, 0)) def send_AuthenticationClearText(self): self.send_to_socket(struct.pack("!cii", ''R'', 8, 3)) if __name__ == "__main__": server = SocketServer.TCPServer(("localhost", 9876), Handler) try: server.serve_forever() except: server.shutdown()

Ejemplo de línea de comando sesión psql:

[~] $ psql -h localhost -p 9876 Password: psql (9.1.6, server 0.0.0) WARNING: psql version 9.1, server version 0.0. Some psql features might not work. Type "help" for help. codeape=> Select; abc | def -----+----- | | (2 rows) codeape=>

Un controlador ODBC que hable el protocolo Postgresql debería funcionar también (pero aún no lo he probado).


Información adicional sobre esto: tenga en cuenta que ya no es tan complejo usar un SDK. Como Kyle sugirió anteriormente, construir un controlador odbc personalizado ya no es tan complejo. Con una solución como OpenAccess, ya se proporciona el 99% del código y usted implementa solo 12 funciones. Puede elegir cualquiera de los siguientes idiomas para codificar: C / C ++, Java, .NET, C #, ABL o 4GL. Para obtener más información sobre cómo comenzar, lea este blog: https://www.progress.com/blogs/quick-guide-build-custom-odbc-driver-in-java-or-c