Delphi's GetTableNames sometimes returns tables with owner names, and sometimes not - delphi

I have some apps that connect to ODBC databases using ADO, and BDE. I have to call GetTableNames to return a list of table. Sometimes, I find that the table names are qualified with owner names, and sometimes not. The permutations are mysterious to me. Anyone can shed light on this?

Most DBMS these days provide a way to retreive a list of tablenames in a result set. I would suggest this approach rather than using the built in GetTableNames function.
For example, on MySQL it is
SHOW TABLES
on MS SQL Server it is:
SELECT name FROM <database name>..sysobjects where xtype = 'U';
Hope that helps

Related

Find changes quickly in larger SQL database?

There is a Java Swing application which uses an Informix database. I have user rights granted for the Swing application (i.e. no source code), and read only access to a mirror of the database.
Sometimes I need to find a database column, which is backing a GUI element (TextBox, TableField, Label...). What would be best approach to find out which database column and table is holding the data shown e.g. in a TextBox?
My general approach is to capture the state of the database. Commit a change using the GUI and then capture the state of the database again. Then I need to examine the difference. I've already tried:
Use the nrows field of systables: Didn't work, because the number in nrows does not seem to be a realtime representation of the row count.
Create a script with SELECT COUNT(*) ... for all tables: didn't work because too many tables (> 5000). Also tried to optimize by removing empty tables, but there are still too many left.
Is there a simple solution that I'm missing?
Please look at the Change Data Capture API and check if this suits your needs
There probably isn't a simple solution.
You probably need to build yourself a map of the database, or a data dictionary for it. It sounds as though you can eliminate many of the tables from consideration since they're empty — at least for a preliminary pass. If you're dealing with information in a text box, the chances are it is some sort of character data; you can analyze which (non-empty) tables which contain longer character strings, and they'd be the primary targets of your searches. If the schema is badly designed with lots of VARCHAR(255) columns even though the columns normally only hold short strings, life is more difficult. Over time, you can begin to classify tables and columns so that you end up knowing where to look for parts of the application.
One problem to beware of: the tabid in informix.systables isn't necessarily as stable as you'd like. Your data dictionary needs to record its own dd_tabid for the table it describes, and can store the last known tabid from informix.systables, but it needs to be ready to find a new tabid value on occasion. You should probably only mark data in your dictionary for logical deletion.
To some extent, this assumes you can create a database in which to record this information. If you can't create an Informix database, you may have to use something else (MySQL, or SQLite, perhaps) to store the data dictionary. Alternatively, go to your DBA team and ask them for the information. Unless you're trying something self-evidently untoward, they're likely to help (but politics can get in the way — I've no idea how collegial your teams are).

SSIS Merge Join component wrote 0 rows

First of all, thanks to the community for the amount of information on the site, helped me a lot with C# and SSIS. The second thing is that i'm not very good with english, so please be patient, if you don't understand something, please ask, i'll try to make it better.
I got 2 OLEDB connection source from different databases, both tables got a column with an ID that I use as a Join Key. In RUT CRUZADOS, the ID its a float datatype, while in the other source (CTACTE AÑO PAS) I don't know which type of data it is (I can't open the database with sql server, i can only do SELECT operations).
When I combine them in the Merge,it doesn't return me any mistake, but when I run the program, this happens.
[SSIS.Pipeline] Information: "component "CARGOS ABONOS" (239)" wrote 0
rows.
In Microsoft Access, the "Inner Join" returns like 4 Millions of rows. I think the problem its the metadata but i dont know how to use the "Data Conversion". Can someone help me please.
Thank you all
You can view the data types, at least as far as SSIS is concerned by double clicking on connector lines. In the Data Flow Path Editor that pops up, the Metadata tab will describe the column types.
That said, it doesn't matter because the Merge Join transformation is only going to allow you to merge data of the same type.
A Merge Join requires the source system data to be sorted. This is accomplished by either adding sort components into the stream (not recommended as this is an asynchronous transform that eats all your memory and kills your performance) or by explicitly sorting in your source systems and then marking them as sorted in the Advanced tab.
Since I don't see a Sort, that leads me to believe the sort is done in the source systems. Or, the sorts are not done there but someone has marked the output as sorted. There must be explicit ORDER BY clauses in those source queries. Sometimes, SQL Server will return data in the same order but unless there is an ORDER BY, it cannot be guaranteed. (I wish I could use the flash tag to emphasis the last point).
Future readers, if you have a sort in both systems and they are both sorted on the same column, then you need to examine collations. Case Insensitive is a different beast than Case Sensitive and a sort on an ASCII based system yields a different sort than one using EBCIDIC for mixed alpha-numeric like I once had...
As the source data type appears to be floats, then sorting is not the likely culprit. The realization is dawning on me, instead of sort issues, you likely have an uglier and more insidious comparison issue. Floating point numbers are approximations. 1=1 but 1.00000000000(etc) may or may not be equal to 1.0000000000(etc)1
Do you actually need the decimal places to make the match? If not, casting to an integer in both (and sorting on the CAST'ed value) systems should make these matches work. If there are decimal places that matter, then you're going to need to cast that into an exact numeric type (and pray that they both convert in the same way). The fact that Access does it leads me to believe Integer data type will be your salvation.

Inserting into multiple tables

I am using Delphi2010 and I'm trying to do an insert into multiple tables. I don't know the best way to do this. What I'm wondering is if there is a possible way to do one insert using one of Delphi's tools like the TQuery or TClientDataSet or would it be better to use code (we use Pascal language). An array maybe? I haven't been using Delphi that long but I have inserted and updated info into one table before, not multiple. Also, these tables use pretty much the same field names.
Any help would be greatly appreciated.
Thanks in advance!!
Call a stored procedure to update your tables simultaneously, with a transaction wrapper. Or re-design your database to eliminate duplicate/redundant data, so that you would never need to update several tables at once.
Note that this answer is perfectly valid, given the information provided in the question...
(Note: it's late, couldn't sleep, bored. This is what you get, given the quality of the information in the question!)
Another possible solution could be to make a updateable view on the database, and update the view from Delphi.
Making a updateable view just moves the work of updating 2 tables to the SQL instead of in Delphi.
This moves the business logic to the sql instead of in the Delphi. It propobly also generates less network trafic.
As Chris writes: use transactions, when 2 or more updates/inserts is dependent of each other.
Which data access componentes do you use ?
Which restrictions do you have ?
do you want to insert the same values into both tables ?
why not easy like:
for i = low(tables) to high(tables) do
begin
query.sql.text := 'insert into '+tables[i]+' (fields) values('+ ...)';
query.execsql;
end;

Delphi, Csv,Import Firebird

Lemme explain my problem.
I have One ID and 2 Other Fields in a CsV file. the ID connected to a database table.
I have to show the curresponding entries in the db and fields from Csv. Need sort the Fields too.
My Idea was load into a ClientDataset, lookup to a Query with table and Use sort and show.
My Csv have 85 K Records and its taking 120 seconds to load and sort, Its not acceptable. Can you tell me, can I use Bacthmove for this. So I can easily pick fields by a simple query. if I can use Batchmove please give me the guidelines.
Also Is there any other Techniques for this?
Thanks and Regards,
Vijesh V.Nair
May be you can take a look in global temporary table but I don't think it will be quicker
i often convert database from csv file to firebird server too.
usually i do like these
- use ms excel to read this csv file first to see if this file is not corrupt.
- still using excel, save this csv file to xls format, close ms excel after converting.
- using axolot component (xlsreadwrite) (www.axolot.com) , try to read cell by cell and insert them to memory table.
- using fibplus component (www.devrace.com), insert them to firebird server.
- job done, going home.
In this case, of course you must prepare your firebird server too. After converting finished, everything is easy actually. you can use uib component (www.progdigy.com) too to connect to firebird server. do not use ibexpress component (ibx) cause of it's author EXPLICITLY state that ibx is never intended for firebird.

MSSQL2000: Using a stored procedure results as a table in sql

Let's say I have 'myStoredProcedure' that takes in an Id as a parameter, and returns a table of information.
Is it possible to write a SQL statement similar to this?
SELECT
MyColumn
FROM
Table-ify('myStoredProcedure ' + #MyId) AS [MyTable]
I get the feeling that it's not, but it would be very beneficial in a scenario I have with legacy code & linked server tables
Thanks!
You can use a table value function in this way.
Here is a few tricks...
No it is not - at least not in any official or documented way - unless you change your stored procedure to a TVF.
But however there are ways (read) hacks to do it. All of them basically involved a linked server and using OpenQuery - for example seehere. Do however note that it is quite fragile as you need to hardcode the name of the server - so it can be problematic if you have multiple sql server instances with different name.
Here is a pretty good summary of the ways of sharing data between stored procedures http://www.sommarskog.se/share_data.html.
Basically it depends what you want to do. The most common ways are creating the temporary table prior to calling the stored procedure and having it fill it, or having one permanent table that the stored procedure dumps the data into which also contains the process id.
Table Valued functions have been mentioned, but there are a number of restrictions when you create a function as opposed to a stored procedure, so they may or may not be right for you. The link provides a good guide to what is available.
SQL Server 2005 and SQL Server 2008 change the options a bit. SQL Server 2005+ make working with XML much easier. So XML can be passed as an output variable and pretty easily "shredded" into a table using the XML functions nodes and value. I believe SQL 2008 allows table variables to be passed into stored procedures (although read only). Since you cited SQL 2000 the 2005+ enhancements don't apply to you, but I mentioned them for completeness.
Most likely you'll go with a table valued function, or creating the temporary table prior to calling the stored procedure and then having it populate that.
While working on the project, I used the following to insert the results of xp_readerrorlog (afaik, returns a table) into a temporary table created ahead of time.
INSERT INTO [tempdb].[dbo].[ErrorLogsTMP]
EXEC master.dbo.xp_readerrorlog
From the temporary table, select the columns you want.

Resources