Search through a table with user input - user-input

This is my script:
select * from cliente
where NOME_CLIENTE like (Upper('&supplier_name') || '%');
and it all gives me "no rows selected".
Why does this happen? And how to fix it?

According to the description, you need to have the wildcard '%' before the user input as well, here is the example:
select * from cliente
where NOME_CLIENTE like ('%' || upper('&supplier_name') || '%');

Related

Issue while forming regex string in a stored procedure

I am trying to run the below query in a stored procedure and its not working.
We tried to print the query using NOTICE and we saw E gets appended to the regex and thats the reason the query doesnt show any output.
Not working
select order,version from mytable
where substring(version from quote_literal('[0-9]+\.[0-9]{1}'))
IN ('6.2') and order= 'ABC';
But the same query if i run from pgadmin query tool, it works fine.
Working
select order,version from mytable
where substring(version from '[0-9]+\.[0-9]{1}')
IN ('6.2') and order= 'ABC';
My requirement is to form the reqex dynamically in the stored procedure. Please guide on how to achieve this.
Below is the line of code in my stored procedure,
sql_query = sql_query || ' AND substring(version from ' || quote_literal( '[0-9]+\.[0-9]{1}' ) || ') IN (' || quote_literal(compatibleVersions) || ')';
raise notice 'Value: %', sql_query;
EXECUTE sql_query INTO query_result ;
and from notice i am getting the below output,
AND substring(version from E'[0-9]+\\.[0-9]{1}') IN ('{6.2}')
My requirement is to make this regex work.
I narrowed down to this query,
working
select substring(version from '[0-9]+\.[0-9]{1}') from mytable ;
not working
select substring(version from quote_literal('[0-9]+\.[0-9]{1}')) from mytable ;
Now i think its easy to fix it. You can try at your end also running this above queries.
Since your problem is not really the extended string literal syntax using E, but the string representation of the array in the IN list, your PL/pgSQL should look somewhat like this:
sql_query = sql_query ||
' AND substring(version from ' || quote_literal( '[0-9]+\.[0-9]{1}' ) ||
') IN (' || (SELECT string_agg(quote_literal(x), ', ')
FROM unnest(compatibleVersions
) AS x(x)) || ')';
quote_literal should be used in situations where u want to dynamically construct queries. In such situation quote_literal will be replaced by E in the final constructed query.
right way to use
select * from config_support_module where substring(firmware from '[0-9]+\.[0-9]{1}') IN ('6.2');
select * from config_support_module where substring(firmware from E'[0-9]+\.[0-9]{1}') IN ('6.2') ;
wrong usage of quote_literal in static queries
select * from config_support_module where substring(firmware from quote_literal('[0-9]+\.[0-9]{1}')) IN ('6.2') ;
This doesnt give you any errors/output.
quote_literal usage in dynamic queries
sql_query = sql_query || ' AND substring(version from ' || quote_literal( '[0-9]+\.[0-9]{1}' ) || ') ... .. ...

Table and column names in dynamic PostgreSQL queries

I'm struggling with a stored procedure which heavily uses dynamic queries. Among others I need to store maximum value of an existing column into a variable.
Postgres documents state "if you want to use dynamically determined table or column names, you must insert them into the command string textually". Based on that I've come up with following statement:
EXECUTE 'SELECT MAX(' || pkColumn::regclass || ') FROM ' ||
tableName::regclass INTO maxValue;
Table name seems to be OK, column name triggers error.
What am I doing wrong ?
Pavel
EXECUTE 'SELECT MAX(' || pkColumn ||'::regclass) FROM ' || ...
::regclass is a cast done inside query. You can also skip it, or put " - which in PG works the same. So please try one of:
EXECUTE 'SELECT MAX(' || pkColumn || ') FROM ' || ...
or
EXECUTE 'SELECT MAX("' || pkColumn || '") FROM ' || ...
All tree should work. If not - just let me know. In that case it is my fault, postgresql simply works.
There is no reason to cast parameters as they are just identifiers. For better control and readability use the function format(), e.g.:
declare
pkcolumn text = 'my_column';
tablename text = 'my_table';
...
execute format('select max(%I) from %I', pkcolumn, tablename)
into maxvalue;

Postgresql - full text search index - unexpected query results

I have a table with a bunch of cols
I have created a full text index on a table like this:
CREATE INDEX phrasetable_exp_idx ON msc.mytable
USING gin(to_tsvector('norwegian', coalesce(msc.mytable.col1,'') || ' ' ||
coalesce(msc.mytable.col2,'') || ' ' ||
coalesce(msc.mytable.col3,'') || ' ' ||
coalesce(msc.mytable.col4,'') || ' ' ||
coalesce(msc.mytable.col5,'') || ' ' ||
coalesce(msc.mytable.col6,'') || ' ' ||
coalesce(msc.mytable.col7,'')));
I try some searches and they are lightning fast, however, for one particular search I don't get the expected results.
I have a row in my table where both col1 and col2 have the exact value "Importkompetanse Oslo AS"
in col3 it has the value "9999".
Only the query to_tsquery('9999') returns the row, which shows me that it does have the value "Importkompetanse Oslo AS" in the both col1 and col2, but the first two queries return no matches.
SELECT *
FROM msc.mytable
WHERE to_tsvector('norwegian', coalesce(msc.col1,'') || ' ' ||
coalesce(msc.mytable.col2,'') || ' ' ||
coalesce(msc.mytable.col3,'') || ' ' ||
coalesce(msc.mytable.col4,'') || ' ' ||
coalesce(msc.mytable.col5,'') || ' ' ||
coalesce(msc.mytable.col6,'') || ' ' ||
coalesce(msc.mytable.col7,'')));
## --to_tsquery('Importkompetanse&Oslo&AS') -- nada
plainto_tsquery('Importkompetanse') -- nada
--to_tsquery('9999') -- OK!
Does anyone have an idea why my searches yields no results?
EDIT:
For some reason, to_tsquery returns something like this:
"'9999':9 'importkompetans':1,6"
The word importkompetanse seems to be cut off?
However, if I set it to simple instead of norwegian, I get the expected results and everything looks good. Why is that?
You used cross configuration between your tsvector and tsquery values. You should use consistent configuration, like:
select to_tsvector('norwegian', 'Importkompetanse Oslo AS')
## to_tsquery('norwegian', 'Importkompetanse&Oslo&AS');
SQLFiddle
This is why it worked with the 'simple' configuration (that is your default).
Note: you can always debug text search with ts_debug(): f.ex. 'Importkompetanse' has not been cut off, 'importkompetans' is just the appropriate lexeme for this word (in the 'norwegian' configuration).
Off: you use a really long, expression-based index, which will only be used, if you use the exact expression in your queries too. You used it right in your example, but this makes your queries really long, and if you change your index expression some time later, you need to make sure all "uses" updated as well.
You could use a simple (sql) function, to simplify your queries:
create or replace function col_tsvector(mytable)
returns tsvector
immutable
language sql
as $function$
return to_tsvector('norwegian',
coalesce($1.col1, '') || ' ' ||
coalesce($1.col2, '') || ' ' ||
coalesce($1.col3, '') || ' ' ||
coalesce($1.col4, '') || ' ' ||
coalesce($1.col5, '') || ' ' ||
coalesce($1.col6, '') || ' ' ||
coalesce($1.col7, ''))
$function$;
With this, you can greatly simplify your index definition & your queries too. (You can even use the attribute notation.)

automatically selecting databasis and columns and searching data

Is it possible to write a query that automatically selects all database names and column names from dbc.Columns table in Teradata, and searches a particular set of values?
Set of values:
WHERE abc in (1,2,3)
Selecting dbc.columns:
SELECT DatabaseName, TableName FROM dbc.COLUMNS
WHERE ColumnName LIKE '%abc%'
How can I combine this and make a query that will return only those combinations of DatabaseName and TableName where ColumnName has specific subset of values?
UPDATE:
This query finds all database - column combinations:
SELECT TRIM(BOTH FROM a.DatabaseName) || '.' || TRIM( BOTH FROM a.TableName)
FROM dbc.COLUMNS AS a
WHERE ColumnName LIKE '%abc%'
is it possible to define some variables or sthg. else?
You need to write Dynamic SQL statements like
SELECT
'SELECT ''' || DatabaseName || '.' || TableName || '.' || ColumnName || ''''
' WHERE EXISTS (SELECT * FROM ' || DatabaseName || '.' || TableName ||
' WHERE ' || ColumnName || ' IN (1,2,3));'
FROM dbc.ColumnsVX
WHERE ColumnName LIKE '%abc%';
Running the resulting queries will return one result set with zero or one row for each table.
To get a single result set you need to write a Stored Procedure with a cursor on the dbc.columnsVX result (adding an INSERT INTO temptable), EXECTE IMMEDIATE each row. Finally return the rows of the temptable.
Unless you're an experienced SQL programmer your DBA will not grant you the right to create SPs.
But why do you actually need this kind of info? Looking for a needle in a haystack?

How to express PostgreSQL variable as a string

Is there any way how to express a variable in PostgreSQL as a string?
Example:
\set table_name countries
SELECT 'SELECT * FROM ' || CAST( :table_name, 'text' ) AS specificQuery;
leads to this error:
ERROR: syntax error at or near ","
LINE 1: SELECT 'SELECT * FROM ' || CAST( countries, 'text' ) AS specificQuery;
From the line sample above is obvious, that it doesn't convert "countries" to a string, but it is expressed as name of column/table.
How do I convert it?
Are you looking for something like this?:
SELECT * FROM :"table_name";
http://www.postgresql.org/docs/current/interactive/app-psql.html#APP-PSQL-VARIABLES
Something like this :
SELECT 'SELECT * FROM ' || countries::text AS specificQuery;