Read number of columns and their type from query result table (in C) - sql

I use PostgreSQL database and C to connect to it. With a help from dyntest.pgc I can access to number of columns and their (SQL3) types from a result table of a query.
Problem is that when result table is empty, I can't fetch a row to get this data. Does anyone have a solution for this?
Query can be SELECT 1,2,3 - so, I think I can't use INFORMATION SCHEMA for this because there is no base table.

I'm not familiar with ecpg, but with libpq you should be able to call PQnfields to get the number of fields and then call various PQf* routines (like PQftype, PQfname) to get detailed info. Those functions take a PGResult, which you have even if there are no rows.

Problem is that when result table is empty, I can't fetch a row to get this data. Does anyone have a solution for this?
I am not sure to really get what you want, but it seems the answer is in the question. If the table is empty, there are no rows...
The only solution here seems you must wait a non empty result table, and then get the needed informations.

Related

How to get the data of the newly accessed record by a query on PostgreSQL using it's internal variables and functions?

Let's say I have the following 'items' table in my PostgreSQL database:
id
item
value
1
a
10
2
b
20
3
c
30
For some reason I can't control I need to run the following query:
select max(value) from items;
which will return 30 as the result.
At this point, I know that I can find the record that contains that value using simple select statements, etc. That's not the actual problem.
My real questions are:
Does PostgreSQL know (behind the scenes) what's is the ID of that
record, although the query shows only the max value of the column
'value'?
If yes, can I have access to that information and,
therefore, get the ID and other data from the found record?
I'm not allowed to create indexes and sequences, or change way the max value is retrieved. That's a given. I need to work from that point onward and find a solution (which I have, actually, from regular query work).
I'm just guessing that the database knows in which record that information (30) is and that I could have access to it.
I've been searching for an answer for a couple of hours but wasn't able to find anything.
What am I missing? Any ideas?
Note: postgres (PostgreSQL) 12.5 (Ubuntu 12.5-0ubuntu0.20.10.1)
You can simply extract the whole record that contains max(value) w/o bothering about Postgres internals like this:
select id, item, "value"
from items
order by "value" desc
limit 1;
I do not think that using undocumented "behind the scenes" ways is a good idea at all. The planner is smart enough to do exactly what you need w/o extra work.

SQL search query on most relevant records

I'm having a table with 6 columns and I want to perform a select query based on all 6 columns, but one column's data is mistyped/incorrect and I get no data returned. What could be used to still have my data returned even though some data is incorrect, but I still want most relevant records to be returned?
Don't know how much this can help you, But you can give a try using SOUNDEX function in SQL server.
Check this link for information on SOUNDEX Function

PL/SQL Cursor rows

I've a question and I hope that I find someone who can help Me:
I want to calculate all the rows returned by the cursor into the 'IF' (whitout using a counter because I want to know the number of rows in one time before begin the treatments.
TO EXPLAIN MORE: I have a table that contains measurements, and I want to know if the test (code inside my IF) returns a lot of mesurements or Not. If it returns One I want to send a message, else I send a message that contains a lot of mesurements .
Thank you
I think this will depend on what you mean by 'a lot' of measurements. nilsman's approach will get you the answer you want. However you will have to execute the cursor again if you actually want the data.
I can think of two approaches that might give you the answer you want
open your cursor using BULK COLLECT. You can then use the COUNT method on the collection you fetched into. However normally we would limit the number of rows collected at any one time to a few hundred at the most. If your definition of 'a lot' is bigger than a few hundred then this approach may not be efficient
use the analytic function COUNT(*) OVER () to return the count of all records in-line with each row of the query. This means after the first fetch you'll know the size of the entire result set
Seems like you need to use SQL%ROWCOUNT.
Look at https://docs.oracle.com/cloud/latest/db112/LNPLS/static.htm#CIHJJJDG for more info.

Hide Empty columns

I got a table with 75 columns,. what is the sql statement to display only the columns with values in in ?
thanks
It's true that a similar statement doesn't exist (in a SELECT you can use condition filters only for the rows, not for the columns). But you could try to write a (bit tricky) procedure. It must check which are the columns that contains at least one not NULL/empty value, using queries. When you get this list of columns just join them in a string with a comma between each one and compose a query that you can run, returning what you wanted.
EDIT: I thought about it and I think you can do it with a procedure but under one of these conditions:
find a way to retrieve column names dynamically in the procedure, that is the metadata (I never heard about it, but I'm new with procedures)
or hardcode all column names (loosing generality)
You could collect column names inside an array, if stored procedures of your DBMS support arrays (or write the procedure in a programming language like C), and loop on them, making a SELECT each time, checking if it's an empty* column or not. If it contains at least one value concatenate it in a string where column names are comma-separated. Finally you can make your query with only not-empty columns!
Alternatively to stored procedure you could write a short program (eg in Java) where you can deal with a better flexibility.
*if you check for NULL values it will be simple, but if you check for empty values you will need to manage with each column data type... another array with data types?
I would suggest that you write a SELECT statement and define which COLUMNS you wish to display and then save that QUERY as a VIEW.
This will save you the trouble of typing in the column names every time you wish to run that query.
As marc_s pointed out in the comments, there is no select statement to hide columns of data.
You could do a pre-parse and dynamically create a statement to do this, but this would be a very inefficient thing to do from a SQL performance perspective. Would strongly advice against what you are trying to do.
A simplified version of this is to just select the relevant columns, which was what I needed personally. A quick search of what we're dealing with in a table
SELECT * FROM table1 LIMIT 10;
-> shows 20 columns where im interested in 3 of them. Limit is just to not overflow the console.
SELECT column1,column3,colum19 FROM table1 WHERE column3='valueX';
It is a bit of a manual filter but it works for what I need.

Oracle extractValue failing when query returns many rows

I have the probably unenviable task of writing a data migration query to populate existing records with a value for a new column being added to a table on a production database. The table has somewhere in the order of 200,000 rows.
The source of the value is in some XML that is stored in the database. I have some XPath that will pull out the value I want, and using extractValue to get the value out seems all good, until the number of records being updated by the query starts getting larger than the few I had in my test DB.
Once the record set grows to some random amount of size, somewhere around 500 rows, then I start getting the error "ORA-19025: EXTRACTVALUE returns value of only one node". Figuring that there was some odd row in the database for which there wasn't a unique result for the XPath, I tried to limit down the records in the query to isolate the bad record. But as soon as I shrunk the record set, the error disappeared. There is actually no row that will return more than one value for this XPath query. It looks like there's something fishy happening with extractValue.
Does anyone know anything about this? I'm not an SQL expert, and even then have spent more time on SQL Server than Oracle. So if I can't get this to work I guess I'm left to do some messing with cursors or something.
Any advice/help? If it helps, we're running 10g on the server. Thanks!
It's almost certain that at least one row from the table with the source XML has an invalid value. Rewrite the query to try and find it.
For example, use the XMLPath predicate that would give you the node in the second position (I don't currently have access to a db with XML objects, so I can't guarantee the following is syntactically perfect):
SELECT SourceKey
, EXTRACTVALUE(SourceXML, '/foo/bar/baz[1]')
, EXTRACTVALUE(SourceXML, '/foo/bar/baz[2]')
FROM SourceTable
WHERE EXTRACTVALUE(SourceXML, '/foo/bar/baz[2]') IS NOT NULL;