SQL Server openrowset() test column count in MS Access table - tsql

Haven't found an answer via Google. I need to execute this code from SQL Server stored proc.
I have a folder with 100+ access dbs with a table called tblReports. Some of the access db's have an extra column in tblReports called AdminReport.
I need to capture the extra column if it exists, thus... I need to test how many columns are in tblReports so that I can use an if/else statement in the sp to generate the correct sql based on the column count.
I'd love to read your thoughts, here's the relevant snippet.
set #sql = 'Insert into CustomerServiceIntranet.dbo.ReportCriteria
(UserInfo,RptNbr,RptType,RptDesc,GroupCDBrk,ClientCDBrk,CategoryCDBrk,
UserIDBrk,UnitCDBrk,WrkTypeBrk,StatCDBrk,StatDatBrk,
ExperBrk,GroupList,ClientList,CategoryList,UserIDList,BusAreaList,
WrkTypList,StatusList,QueueList,ReviewDay,ReviewDayNA,
ErrorImpact,DateRange,DataSource,RptPathFile)'
+ 'Select '''+ #userfilename + ''', ors.* '
+ 'from (select * From Openrowset(''Microsoft.ACE.OLEDB.12.0'','''
+ #CurrentName
+ ''';''Admin'';,''select * from tblReports'')) ors'

The standard approach would be to link to tblReports by calling DoCmd.TransferDatabase. You would then be able to count number of the fields in the table, before embarking on any SQL. At the end of the look you would delete the link by calling DoCmd.DeleteObject.
It certainly looks neater than what you are trying to do.

Related

Get the ResultSet of an SQL injection

Suppose the server side code is something like that:
String id = getIdFromHttpRequest();
String value = getValueFromHttpRequest();
ResultSet rs = new ResultSet();
String query = "INSERT INTO users VALUES ('" + id + "', '" + value + "');"
rs = SQL.doQuery(query); // i know it's not the syntax, but the point is clear
Well, the injection is easy, I can make it execute an SQL command, but the problem is I want to see the result set (I inject SELECT command).
Is there a way of doing so?
You probably cannot achieve this.
As you know, an INSERT statement has no result set, even if you use SQL injection. At best, you could make it execute a SELECT as a scalar subquery. It's not hard to spoof your example to execute the following:
INSERT INTO users VALUES ('8675309', '' || (SELECT ...blah blah...) || '');
But that still would not return a result set, because INSERT never has a result set.
You would need to execute a second query to do that. Some query interfaces do support multi-query in a single call to doQuery(), but this is not always true (depends on the brand of database you use, and possibly some configuration options).
INSERT INTO users VALUES (...whatever...);
SELECT * FROM secure_table WHERE (id = '8675309');
With SQL injection, you can manipulate the SQL, but you can't manipulate the rest of the code in the application that runs the SQL. In the example you show, the app is designed to run an INSERT query, not an INSERT followed by a SELECT. The app would have no reason to fetch a result set after executing an INSERT.
It's hard to imagine how you could use SQL injection alone to trick the code you show into fetching and displaying a result set.
I don't think it is possible to use SQL injection do read data by exploiting a non-reading query.

finding length of longest coulmn in a database - SELECT subquery

My skills in SQL are limited:
I have a database (SQLBase in this case) that has a couple of LONGVARs in columns.
I'm searching for the actual length of all COLUMNS that have a particular type.
SELECT tbname,name FROM sysadm.syscolumns where coltype='LONGVAR';
The above statement works. It gives me all tables and the respective column names that have a LONGVAR datatype. Now I would like to take these data and search through all the respective tables (the rows, so the data) and find the lengths of the respective LONGVAR columns (to find the maximum for instance, or those above a certain limit).
I have the idea that it can be solved with a subquery of nested SELECT statement but have no idea how to formulate the statement.
I don't have any real knowledge of SQLbase, so I may be off-base here: but if I was trying to do this on SQL Server, a simple approach would be to do something like the following:
SELECT
tbname,
name,
'SELECT ''' + tbname + ''' AS TableName, ''' + name + ''' AS ColumnName, MAX(LEN(' + name + ')) AS ColumnLength FROM ' + tbname + ' -- add a WHERE clause here if needed' AS Query
FROM sysadm.syscolumns
WHERE coltype='LONGVAR';
This will output a set of values, which you could then copy/paste into a new query editor window and examine before running.
Other, more complex solutions would involve dynamic SQL that automatically executes each of these statements; but again, not knowing much about SQLbase, this is where I would start.

How to get data from specific column in firebird using rdb$field_name

how to get data from a specific column in fire bird? something like.
select from rdb$relation_fields
where rdb$relation_name = 'table' and rdb$field_name = 'code'
Your question doesn't quite make sense to me - if you already know the table and field name (as you do in your example) then why not select directly from the table? Anyway, you can create SQL statement dynamically in PSQL as string and then execute it using EXECUTE STATEMENT. The EXECUTE BLOCK might also be of intrest, depends where and what exactly youre tring to achieve.
EDIT after reading the comment
So just build the SELECT statement at the client side, selecting the field currently selected in combobox. You don't mention the language you use but generaaly it something like
query.SQL := 'SELECT '+ comboField.Text +' FROM '+curTableName;
query.Open();
// read the resultset

dynamic sql query in postgres

I was attempting to use Dynamic SQL to run some queries in postgres.
Example:
EXECUTE format('SELECT * from result_%s_table', quote_ident((select id from ids where condition = some_condition)))
I have to query a table, which is of the form result_%s_table wherein, I need to substitute the correct table name (an id) from an another table.
I get the error ERROR: prepared statement "format" does not exist
Link: string substitution with query result postgresql
EXECUTE ... USING only works in PL/PgSQL - ie within functions or DO blocks written in the PL/PgSQL language. It does not work in plain SQL; the EXECUTE in plain SQL is completely different, for executing prepared statements. You cannot use dynamic SQL directly in PostgreSQL's SQL dialect.
Compare:
PL/PgSQL's EXECUTE ... USING; to
SQL's EXECUTE
See the 2nd last par in my prior answer.
In addition to not running except in PL/PgSQL your SQL statement is wrong, it won't do what you expect. If (select id from ids where condition = some_condition) returns say 42, the statement would fail if id is an integer. If it's cast to text you'd get:
EXECUTE format('SELECT * from result_%s_table', quote_ident('42'));
EXECUTE format('SELECT * from result_%s_table', '"42"');
EXECUTE 'SELECT * from result_"42"_table';
That's invalid. You actually want result_42_table or "result_42_table". You'd have to write something more like:
EXECUTE format('SELECT * from %s', quote_ident('result_'||(select id from ids where condition = some_condition)||'_table'))
... if you must use quote_ident.
CREATE OR REPLACE FUNCTION public.exec(
text)
RETURNS SETOF RECORD
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
RETURN QUERY EXECUTE $1 ;
END
$BODY$;
usage:
select * from exec('select now()') as t(dt timestamptz)
Try using
RETURN QUERY EXECUTE '<SQL Command>'
This will return data into form of table. You have to use this into stored function of PostgreSQL.
I have already created on full demonstration on custom filter and custom sorting using dynamic query of PostgreSQL.
Please visit this url:
http://www.dbrnd.com/2015/05/postgresql-dynamic-sql/
These all look more complicated than the OP's question. A different formatting should do the trick.. but it could absolutely the case that I don't understand.
From how I read OP's question, I think others in a similar situation may benefit from how I got it.
I am using Postgre on Redshift, and I ran into this issue and found a solution.
I was trying to create a dynamic query, putting in my own date.
date = dt.date(2018, 10, 30)
query = ''' select * from table where date >= ''' + str(my_date) + ''' order by date '''
But, the query entirely ignores the condition when typing it this way.
However, if you use the percent sign (%), you can insert the date correctly.
One correct way to write the above statement is:
query = ''' select * from table where date >= ''' + ''' '%s' ''' % my_date + ''' order by date '''
So, maybe this is helpful, or maybe it is not. I hope it helps at least one person in my situation!
Best wishes.
EXECUTE will work only on pl/pqsql environment.
instead of EXECUTE try with SELECT
SELECT format('SELECT * from result_%s_table', quote_ident((select id from ids where condition = some_condition))
output would be the dynamic query.

SQL join from multiple tables

We've got a system (MS SQL 2008 R2-based) that has a number of "input" database and a one "output" database. I'd like to write a query that will read from the output DB, and JOIN it to data in one of the source DB. However, the source table may be one or more individual tables :( The name of the source DB is included in the output DB; ideally, I'd like to do something like the following (pseudo-SQL ahoy)
select o.[UID]
,o.[description]
,i.[data]
from [output].dbo.[description] as o
left join (select [UID]
,[data]
from
[output.sourcedb].dbo.datatable
) as i
on i.[UID] = o.[UID];
Is there any way to do something like the above - "dynamically" specify the database and table to be joined on for each row in the query?
Try using the exec function, then specify the select as a string, adding variables for database names and tables where appropriate. Simple example:
DECLARE #dbName VARCHAR(255), #tableName VARCHAR(255), #colName VARCHAR(255)
...
EXEC('SELECT * FROM ' + #dbName + '.dbo.' + #tableName + ' WHERE ' + #colName + ' = 1')
No, the table must be known at the time you prepare the query. Otherwise how would the query optimizer know what indexes it might be able to use? Or if the table you reference even has an UID column?
You'll have to do this in stages:
Fetch the sourcedb value from your output database in one query.
Build an SQL query string, interpolating the value you fetched in the first query into the FROM clause of the second query.
Be careful to check that this value contains a legitimate database name. For instance, filter out non-alpha characters or apply a regular expression or look it up in a whitelist. Otherwise you're exposing yourself to a SQL Injection risk.
Execute the new SQL string you built with exec() as #user353852 suggests.