Are there any new ODBC options for Foxpro? - odbc

We commonly use MS Visual Foxpro v9.0 SP1, the language, tables, and reports. However, sometimes we use an ODBC driver to connect to the tables. The ODBC driver was written for Foxpro v6, and doesn't support certain nested selects, autoincrement fields, or embedded casts.
We would like to find an alternative to what we have. It could be another ODBC driver that works with Visaul Foxpro v9, or a complete alternative to ODBC. Is there such a thing?
Thanks.

(Talk about reuse, just answered this in another thread today)
If you are looking for an ODBC driver for VFP databases and tables you might consider looking at Advantage Database from iAnywhere. The have a local engine and a server engine. The local engine has the engine to access DBF data, but for your case, it also has an ODBC drive that works with VFP data up to and including the current Visual FoxPro 9. The local engine and the included ODBC driver are free.
http://www.sybase.com/ianywhere

You can via COM+ and do almost anything in VFP, however, you have security issues through Admin Tools, Component Services..
You can either build as a single-threaded or multi-threaded DLL.
Once registered, and the typelibrary info is "Add Referenced" to a C# (or other) app, you can make function calls with whatever parameters you need. There are many things you can return back, but typically tables, I send back as XML (via Foxpro's XMLAdapter class), then stream convert to a table once in C#. Its been a while since I worked it that way, but that give tremendous flexibility as you can do your queries, scan loops, and other complex conditional testing and updating of the cursor before generating out the XML and returning it as a string.
DEFINE CLASS YourClass as CUSTOM OLEPUBLIC
FUNCTION GetMyData( lcSomeString as String)
select * from (YourPath + "SomeTable" ) where ... into cursor C_SomeCursor readwrite
.. any other manipulation, testing, etc...
oXML = CREATEOBJECT( "xmladapter" )
lcXML = ""
oXML.AddTableSchema( "C_SomeCursor" )
oXML.ToXML( "lcXML", "", .f. )
return lcXML
ENDFUNC
ENDDEFINE

Related

Is there any good way to pass in bytecode directly to sqlite3?

I'm working on a tool that allows Python developers to write pythonic code to interact with a sqlite3 database, similar to sqlalchemy but without the "translation" phase. If I can generate a sqlite3 prepared statement, how can I directly pass it to the evaluation system?
As a rough example, here's how I roughly view a user being able to interact with my tool:
myTable = Table("field1", "field2", "field3")
mytable.insert("foo", "bar", "baz")
select = mytable.select("field1")
---------------
print(select)
>>> ["foo"]
There is no (public) API in SQLite3 that allows you to execute pre-built SQLite bytecode. The bytecode for an SQL statement can be viewed with the EXPLAIN SQL command, but this is meant for debugging and learning purposes, not for what you're trying to do.
And for most purposes, you shouldn't need this. If you feel that the time spent compiling a prepared statement will be a burden, sqlite3_stmt objects can be stored for the lifetime of the sqlite3 database connection it was created with. Prepared statements that have been executed can be reset, allowing them to be executed again. So as long as the database connection exists, you can compile the statement once and use it as many times as you need to.
But that's about it. There is no mechanism to persist a prepared statement beyond the lifespan of the sqlite3 connection. You can't extract the bytecode by any public API, and you can't use some bytecode you've obtained to reconstitute a prepared statement.
If you want persistence beyond the connection, then you need to store the SQL statement text in whatever place you want to be persistent, and then simply recompile the prepared statement when you reconnect to the database. That one recompilation (or many depending on how many you store) shouldn't be a particular burden, depending on the life span of your application.

Invalid column definition error when using four part name to access Oracle DB as SQL Server linked server

I have setup a linked server in SQL Server 2008 R2 in order to access an Oracle 11g database. The MSDASQL provider is used to connect to the linked server through the Oracle Instant Client ODBC driver. The connection works well when using the OPENQUERY with the below syntax:
SELECT *
FROM OPENQUERY(LINKED_SERVER, 'SELECT * FROM SCHEMA.TABLE')
However, went I try to use a four part name using the below syntax:
SELECT *
FROM LINKED_SERVER..SCHEMA.TABLE
I receive the following error:
Msg 7318, Level 16, State 1, Line 1
The OLE DB provider "MSDASQL" for linked server "LINKED_SERVER" returned an invalid column definition for table ""SCHEMA"."TABLE"".
Does anyone have any insight on what my be causing the four part name query to fail while the OPENQUERY one works without any problems?
The correct path to follow is to use OPENQUERY function because your linked server is Oracle: the four name syntax will work fine for MSSQL servers, essentially because they understand T-SQL.
With very simple queries, a 4 part name can accidentally work but not often if you are in a real scenario. In your case, the SELECT * is returning all the columns, and in your case one of the column definition is not compatible with SQL Server. Try another table or try to select a single simple column (e.g. a CHAR or a NUMBER), maybe it will work without problem.
In any case, using distributed queries can be tricky sometime. Database itself does some optimizations before executing commands, so it is important for the database to know what it can do and what it can't. If the DB thinks the linked server is MSSQL, it will take some action that may not work with Oracle.
When using four part name syntax with a linked DB different from MSSQL, you will have other problems as well, for example using database builtin functions (i.e. to_date() Oracle function will not work because MSSQL would want to use its own convert() function, and so on).
So again, if the linked server is not a MSSQL, the right choice is to use OPENQUERY and passing it a query that use a syntax valid against the linked server SQL dialect.
If you use the OLEDB provider for Oracle you can query without using openquery

Connecting to oracle 11g on Red hat linux from windows server using asp.net

We have our application developed and tested with sql server 2008r2 using ASP.NET on windows server. Now we have a requirement to move the database from windows to oracle on red hat linux.
We haven't yet setup the infrastructure to test the same. I would like to know in the meantime if anyone has successfully done this kind of thing. Pointers to any resources will be a great advantage.
Is changing the connection string the only thing that needs to be done or are there any specific configuration in Linux to allow this?
I will verify this once I get the environment ready, but as a headstart if anyone has any similar experience, do share.
Thanks in advance.
P.S: For migration of table structure, storedprocedures etc to oracle we will be using the Sql Developer tool.
I would like to answer my question,because, migration to oracle is not that straight forward, but there are some tips that may help anyone migrate to oracle on windows or linux with less headache.
The first thing the Sql developer tool does a good job of migrating sqlserver schema and data to oracle including storedprocedures, constraints, triggers etc.
It also does a good job of datatype mapping and provides option to remap datatype if required.
Some caveats and precautions.
Oracle has a limitation on the length of stored procedure names of about 30 characters. This is the area you need to resort to some manual renaming as when migration SP's or identifiers whose name is greater than 30 characters may get truncated.
The other common issue that you may face is respect to date insertion and formatting. You can use the following snippet to avoid the headache. The common error will be "Not a valid month."
OracleConnection conn = new OracleConnection(oradb); // C#
conn.Open();
OracleGlobalization session = conn.GetSessionInfo();
session.DateFormat = "DD.MM.RR"; // change the format as required here
conn.SetSessionInfo(session);
The most annoying error would be well character to numeric conversion when inserting or updating data or related error.
The issue here is when you add parameters to command object for sql provider, the binding happens by name, but forOracle.DataAccess the default binding is by position. Here's the post that saved me lot of headache.
ODP .NET Parameter problem with uint datatype
What you can do is set the command.BindByName = true;
When migrating SP's that returns data, oracle creates an out parameter ref cursor. This needs to be taken care of while constructing command parameters.
For e.g.
OracleParameter refp = new Oracle.DataAccess.Client.OracleParameter("cv_1", OracleDbType.RefCursor, ParameterDirection.InputOutput);
command.Parameters.Add(refp);
Also the sqlserver requires parameters to SP be prefixed with "#" and oracle doesn't. This can be easily taken care of in your data layer.
Also since there is no bit datatype in Oracle, number(1) works fine. You may need to convert your bool to numeric, if required.
Hope this helps someone avoid a migration headaches. I will post more issues if I encounter.

what's the issue with AttachDbFilename

Apparently, using AttachDbFilename and user instance in your connection string is a bad way to connect to a DB. I'm using SQL server express on my local machine and it all seems to work fine. But what's the proper way to connect to SQL server then?
Thanks for your explanation.
Using User Instance means that SQL Server is creating a special copy of that database file for use by your program. If you have two different programs using that same connection string, they get two entirely different copies of the database. This leads to a lot of confusion, as people will test updating data with their program, then connect to a different copy of their database in Management Studio, and complain that their update isn't working. This sends them through a flawed series of wild goose chase steps trying to troubleshoot the wrong problem.
This article goes into more depth about how to use this feature, but heed the very first note: the User Instance feature has been deprecated. In SQL Server 2012, the preferred alternatives are (in this order, IMHO):
Create or attach your database to a real instance of SQL Server. Your connection string will then just need to specify the instance name, the database name, and credentials. There will be no mixup as Management Studio, Visual Studio and your program(s) will all be connecting to a single copy of the database.
Use a container for local development. Here's a great starter video by Anna Hoffman and Anthony Nocentino, and I have some other resources here, here, and here. If you're on an M1 Mac, you won't be able to use a full-blown SQL Server instance, but you can use Azure SQL Edge if you can get by with most SQL Server functionality (the omissions are enumerated here).
Use SqlLocalDb for local development. I believe I pointed you to this article yesterday: "Getting Started with SQL Server 2012 Express LocalDB."
Use SQL Server Compact. I like this option the least because the functionality and syntax is not the same - so it's not necessarily going to provide you with all the functionality you're ultimately going to want to deploy. Compact Edition is also deprecated, so there's that.
Of course if you are using a version < SQL Server 2012, SqlLocalDb is not an option - so you should be creating a real database and using that consistently. I only mention the Compact option for completeness - I think that can be almost as bad an idea as using AttachDbFileName.
EDIT: I've blogged about this here:
Bad Habits : Using AttachDBFileName
In case someone had the problem.
When attaching the database with a connection string containing AttachDBFile
with SQLEXPRESS, I noticed this connection was exclusive to the ASP.NET application that was using the database. The connection did block the access to all other processes on the file level when made with System.Data.SqlClient as provider.
In order to assure the connection to be shareable with other processes
instead use DataBase to specify the database name in your connection string
Example or connection string :
Data Source=.\SQLEXPRESS;DataBase=PlaCliGen;User ID=XXX;password=ZZZ; Connect Timeout=30
,where PlaCliGen is the name (or logical name) by which SQLEXPRESS server knows the database.
By connecting to the data base with AttachDBFile giving the path to the .mdf file
(namely : replacing DataBase = PlacliGen by AttachDBFile = c:\vs\placligen\app_data\placligen.mdf) the File was connected exclusively and no other process could connect to the database.

Pull Sybase data into SQL Server

I have an ASP.NET app that uses a SQL Server database. I now need to pull data from Sybase ASE into that SQL Server database for my app to consume, and I'm not having any success with my ideas.
Has anyone done this? Any ideas/suggestions/tips?
You can configure a linked server from SQL Server to Sybase. It should be fairly vanilla using the Sybase provider on the MS side.
Okay, I've finally (through lame trial and error) found out how to link my Sybase ASE (12.5) server to my SQL Server (2008) which will allow the integration I want. Here's roughly how I did it:
Logged in to Sybase ASE OLE DB Configuration Manager (this is like the Sybase version of Windows' ODBC Data Sources) and added an OLE DB data source. I believe you must be an admin on the PC to do this.
In SQL Server 2008 Management Studio, went to Server Objects > Linked Servers. Right click and select "New Linked Server".
In the Linked Server Properties, I set the following properties:
General:
--Linked server: the name of your linked server as you want it to appear in your linked server list
--Provider: Select Sybase ASE OLE DB Provider from the dropdown list.
--Product name: The exact name of the OLD DB data source you just created in Sybase ASE OLE DB Configuration Manager.
--Data source: Same as Product name.
--Provider string: I left this blank
--Location: I left this blank
--Catalog: The default database (master or whatever) to log on to.
Security:
--You need to map a valid SQL Server logon to a valid Sybase logon. I did not use impersonation (which does a credentials pass-thru).
--I chose my connection Be made without using a security context.
Server Options:
--All the defaults worked for me.
Throughout, the standard SQL Server help worked fairly well as a guide. Though not always true, F1 was my friend here.
I can now do distributed queries, DTS or SSIS packages, and use SSRS. This takes a lot of the suck out of Sybase ASE.
Of course the above can be done via the command line using sp_linkserver, but the GUI is more comfortable for a lowly dev like me.
Use Management Studio or Enterprise Manager to import the data using the data importation wizard. That should be it, just make sure you pick the right data provider in the wizard and you should be good to go.
If you want this to be a live feed create a small windows service to manage the exchange of information. It should be relatively simple to do, just a little bit of leg work on your end. If you are adverse to that there are plenty of off the shelf solutions that can do this for you.
The question is a little vague on specifics:
Is this a one time conversion or part of a repeated process.
Is the source machine "reachable" from your destination machine (can you connect the two or do you need to read in files)
With most conversions there are two parts:
Physically getting data from the source into the destination.
Mapping data from the source to the destination tables.
It is hard to make any recommendations without more info. What would be fine for a one time conversion would not work if you need to read in data all day every day. Also, if the source database can not be connected to and you have to pass files, they methods change.

Resources