nzsql - Using a defined variable inside of a string - netezza

I'm running into a bit of a snag using Netezza's nzsql tool when it comes to using internal variables. The documentation mentions how to set those variables, \set varname value but doesn't make clear how to use them in any meaningful way.
I've worked out that they can be used within queries, but so far I can only use them as identifiers, not strings.
For example, this works fine:
DB.INST1(INST1)=> \set COLNAME 'table_name'
DB.INST1(INST1)=> SELECT :COLNAME FROM _v_sys_columns LIMIT 1;
TABLE_NAME
----------------------------
_V_TABLE_ONLY_STORAGE_STAT
(1 row)
DB.INST1(INST1)=> \p
SELECT table_name FROM _v_sys_columns LIMIT 1;
But this doesn't:
DB.INST1(INST1)=> \set TABLE_NAME 'table_to_search_for'
DB.INST1(INST1)=> SELECT owner, createdate FROM _v_table WHERE tablename = :TABLE_NAME;
ERROR: Attribute 'TABLE_TO_SEARCH_FOR' not found
DB.INST1(INST1)=> \p
SELECT owner, createdate FROM _v_table WHERE tablename = table_to_search_for;
And neither does this (it uses :TABLE_NAME as a text literal, not its contents):
DB.INST1(INST1)=> \set TABLE_NAME 'table_to_search_for'
DB.INST1(INST1)=> SELECT owner, createdate FROM _v_table WHERE tablename = ':TABLE_NAME';
OWNER | CREATEDATE
-------+------------
(0 rows)
DB.INST1(INST1)=> \p
SELECT owner, createdate FROM _v_table WHERE tablename = ':TABLE_NAME';
Is there any way to accomplish what I'm hoping to do? The result I'm hoping to achieve is having nzsql run the following query:
SELECT owner, createdate FROM _v_table WHERE tablename = 'table_to_search_for';

When you want to use the contents of a variable as a literal in nzsql you need to include an additional set of single quotes, escaped with backslashes, around the literal text when you set the variable.
TESTDB.ADMIN(ADMIN)=> \set tvar '\'BLAH\''
TESTDB.ADMIN(ADMIN)=> select :tvar col_alias;
COL_ALIAS
-----------
BLAH
(1 row)
Updating this with an example more relevant to your situation.
TESTDB.ADMIN(ADMIN)=> create table var_table (col1 bigint);
CREATE TABLE
TESTDB.ADMIN(ADMIN)=> \set TABLE_NAME '\'VAR_TABLE\''
TESTDB.ADMIN(ADMIN)=> SELECT owner, createdate FROM _v_table WHERE tablename = :TABLE_NAME;
OWNER | CREATEDATE
-------+---------------------
ADMIN | 2015-01-13 06:52:36
(1 row)

You can embed the contents of a variable in a string. The trick is making a new variable (quoted_foo in the below example) which contains a single quote, your variable's contents, and another single quote.
DB.TST(LLAMA)=> SELECT * FROM example_table WHERE example_column LIKE '%ello%';
EXAMPLE_COLUMN
----------------
Hello World
(1 row)
DB.TST(LLAMA)=> \set foo ello
DB.TST(LLAMA)=> \set quoted_foo '\'' :foo '\''
DB.TST(LLAMA)=> \echo :quoted_foo
'ello'
DB.TST(LLAMA)=> SELECT * FROM example_table WHERE example_column LIKE '%' || :quoted_foo || '%';
EXAMPLE_COLUMN
----------------
Hello World
(1 row)
For more about session variables in nzsql including using variables as part of table and column names, see this answer.

Related

Postgresql put strings inside quotes with array_to_string

In select I have used array_to_string like this (example)
array_to_string(array_agg(tag_name),';') tag_names
I got resulting string "tag1;tag2;tag3;..." but I would like to get resulting string as "'tag1';'tag2';'tag3';...".
How can I do this in Postgres?
Use the functions string_agg() and format() with the %L placeholder, which quotes the argument value as an SQL literal.
with my_table(tag_name) as (
values
('tag1'),
('tag2'),
('tag3')
)
select string_agg(format('%L', tag_name), ';' order by tag_name) tag_names
from my_table;
tag_names
----------------------
'tag1';'tag2';'tag3'
(1 row)
Alternatively, format('%L', tag_name) may be replaced with quote_nullable(tag_name).
Or your can use unnest, format, array_agg and array_to_string in one request like this :
select array_to_string(t.tag, ',')
from (
select array_agg(format('%L', t.tag)) as tag
from (
select unnest(tag_name) as tag
) t
) t;
Or use
array_to_string(array_agg(''''||tag_name||''''),';') tag_names
or even simpler (thanks for the commenting :) )
string_agg(''''||tag_name||''''),';') tag_names
Note:
When dealing with multiple-argument aggregate functions, note that the
ORDER BY clause goes after all the aggregate arguments. For example,
write this:
SELECT string_agg(a, ',' ORDER BY a) FROM table;
not this:
SELECT string_agg(a ORDER BY a, ',') FROM table; -- incorrect
See https://www.postgresql.org/docs/current/static/sql-expressions.html#SYNTAX-AGGREGATES
You can use string_agg() function with '''; ''' so it will be like
SELECT string_agg(tag_name, '''; ''') from my_table

SQL Server : SELECT from a string

I am struggling with this: I have two SQL statements that have 2 different sets of keywords. These are stored in temporary tables since I cannot update, delete or insert into a table.
How do I write a third SQL statement (limited on SQL characters in each statement) that says: "If 'pingu' and 'noot' is correct then true, otherwise if 'sponge' and 'bob' are true display results" (this works)? But then how do I say: "if 'pingu' and 'sponge' is selected then true, or 'bob' and 'noot' are selected then true", but keeping the 'pingu' and 'noot' as true if selected?
Example of keyword list 1: 'Pingu' and 'Noot'
DECLARE #teststring varchar(512) = '{KEYWORD}'
SELECT TOP 1 k.type
FROM (VALUES
('pingu', '66'), ('noot', '66'))
k(word,type) WHERE #teststring LIKE '%' + k.word + '%'
GROUP BY k.type
HAVING COUNT(1) >=2
ORDER BY COUNT(1) DESC;
Example of keyword list 2: 'Sponge' and 'Bob'
DECLARE #teststring varchar(512) = '{KEYWORD}'
SELECT TOP 1 k.type
FROM (VALUES ('sponge', '66'), ('bob', '66')) k (word, type)
WHERE #teststring LIKE '%' + k.word + '%'
GROUP BY k.type
HAVING COUNT(1) >= 2
ORDER BY COUNT(1) DESC;
What about combining the two source queries with a UNION ALL?
For example (adapting your original queries):
DECLARE #teststring varchar(512) = '{KEYWORD}';
WITH Keywords AS (
SELECT *
FROM (VALUES ('pingu', '66'), ('noot', '66')) k(word, type)
UNION ALL
SELECT *
FROM (VALUES ('sponge', '66'), ('bob', '66')) k(word, type)
)
SELECT TOP 1 k.type
FROM Keywords k
WHERE #teststring LIKE '%' + k.word + '%'
GROUP BY k.type
HAVING COUNT(1) >=2
ORDER BY COUNT(1) DESC;
This returns a result row if at least two keywords, regardless of which source query the keywords come from, are found in #teststring.
Note: If your keywords lists are large, it may be worth reworking the query so that an index can be used to make processing the WHERE clause more efficient.

How to remove double quotes within a column in SQL server 2012

I need to remove double quotes within a column value. For example, I have a column in table which has values as below
"Testing Name ("Inc")"
"Testing, "Trust" ("Inc")"
I need to remove the double quotes surrounding the "Inc" & "Trust" and column values should resemble as below
"Testing Name (Inc)"
"Testing, Trust (Inc)"
I tried with REPLACE() function. But it replaces all the double quotes in a value. But I want to retain the quotes at start and end of the value. Kindly help
Use Replace to remove double quotes from string. And then Prefix, Suffix with double quotes.
DECLARE #VAR VARCHAR(50)='"Testing Name ("Inc")"'
CREATE TABLE #TAB (COLUMN_VALUE VARCHAR(50))
INSERT INTO #TAB
SELECT '"Testing Name ("Inc")"'
UNION ALL
SELECT '"Testing, "Trust" ("Inc")"'
Now hit below SELECT statement
SELECT COLUMN_VALUE, '"'+REPLACE(COLUMN_VALUE,'"','') +'"' as NEW_COLUMN_VALUE FROM #TAB
And the result will be
+----------------------------+------------------------+
| COLUMN_VALUE | NEW_COLUMN_VALUE |
+----------------------------+------------------------+
| "Testing Name ("Inc")" | "Testing Name (Inc)" |
| "Testing, "Trust" ("Inc")" | "Testing, Trust (Inc)" |
+----------------------------+------------------------+
IF start and end of the value will always contains double quotes, then try the below script.
SELECT '"'+REPLACE( [column],'"','')+'"'
FROM [table]
Following code checks if there is a '"' at the start and end of the string and then replaces '"' and concatenates '"' to start and end of the string. If the string doesn't have '"' at the start and end of the string, it just replaces '"' in all the positions of the string and does not concatenate it to start and end.
CREATE TABLE #TAB (COLUMN_VALUE VARCHAR(50))
INSERT INTO #TAB
SELECT '"Testing Name ("Inc")"'
UNION ALL
SELECT '"Testing, "Trust" ("Inc")"'
union all
select 'Testing Name ("Inc")'
union all
SELECT 'Testing, "Trust" ("Inc")'
union all
SELECT 'Testing, "Trust" ("Inc")"'
select * from #TAB
select
case when charindex('"',column_value,1)=1 and charindex('"',column_value,len(column_value))=len(column_value)
then '"'+REPLACE(COLUMN_VALUE,'"','') +'"'
else REPLACE(COLUMN_VALUE,'"','')
end as ClenedString
from #TAB;

MSSQL quote insensitive search

How to make a quote insensitive search in SQL Server?
For example those city names should be considered equal:
Muggio'
Muggio
I know how to make a simple accent-insensitive search but I found nothing about quote-insensitive searches.
There is a collation or a tidy function I can use? Or I should preprocess the city name in my code?
DECLARE #t TABLE(v VARCHAR(20))
INSERT INTO #t VALUES
('abc'''),
('abc')
DECLARE #f VARCHAR(20) = 'abc'''
SELECT * FROM #t WHERE v LIKE '%' + REPLACE(#f, '''', '') + '%'
Output:
abc'
abc

SQL Server Templates - How Do I Escape The Less Than Character?

I like to use SQL Server 2005 templates to run frequently used queries. You can include parameters in your templates using this syntax:
<LastName, varchar, 'Bob'>
I have a query that needs the less than or equals to operator <= but unfortunately the SQL Server 2005 template interprets that as the start of a parameter. I have been unable to find a way to use the < (less than character) as a literal.
when I Specify Values for Template Parameters, this runs fine for me:
select * from <xyz, varchar,YourTable> WHERE ID<=1000 AND ID>=20000
perhaps you do not have every parameter's "<" and ">" paired properly
EDIT I see the problem now:
SELECT * FROM <xyz, varchar,YourTable> WHERE ID<=1000 AND ID>=20000 AND <xyz2,varchar,YourColumn> IS NOT NULL
results in:
SELECT * FROM YourTable WHERE IDYourColumn IS NOT NULL
try making the "<" character into a parameter, like this:
SELECT * FROM <xyz, varchar,YourTable> WHERE ID<lessthan,char,<>=1000
AND ID>=20000 AND <<xyz2,varchar,YourColumn> IS NOT NULL
it results in:
SELECT * FROM YourTable WHERE ID<=1000
AND ID>=20000 AND YourColumn IS NOT NULL
OR split the lines, line breaks seem to make a difference:
SELECT * FROM <xyz, varchar,YourTable> WHERE ID<=1000 AND ID>=20000
AND <xyz2,varchar,YourColumn> IS NOT NULL
results in:
SELECT * FROM YourTable WHERE ID<=1000 AND ID>=20000
AND YourColumn IS NOT NULL
With template
select top 10 * from syscolumns
where <xtype, varchar(128), xtype <= 60>
If you select (menu) Query > Specify Values for template parameters, the default value for replacement is "xtype <= 60", which is correct, and upon substitution, the resulting query text is
select top 10 * from syscolumns
where xtype <= 60
which is exactly what one would expect. In other words, it does not appear to be the case that the "<" symbol needs to be escaped. However, ">" is more problematic:
select top 10 * from syscolumns
where <xtype, varchar(128), xtype >= 60>
This will fail when opening the "specify values" dialog. However, in this instance, it is fine to specify
select top 10 * from syscolumns
where <xtype, varchar(128), value>
and enter
xtype >= 60
in the "value" field for replacement. This produces
select top 10 * from syscolumns
where xtype >= 60
which is again as one would expect. So it would seem that the default value for replacement may not contain a ">".

Resources