Postgresql Concat String - database

I want to create select Query in Postgresql. my code is
select * into concat('production.',layer_name) from concat('staging.',layer_name);
but there is a problem
ERROR: "concat" is not a known variable
LINE 20: select * into concat('production.'layer_name) from concat('...
I can not understand why .
Can anybody help me?

There is a concat() function in Postgres (since v.9.1). Useful for string concatenation possibly involving NULL values. But your syntax is just gibberish to the Postgres parser. It is generally not possible to use values (or return values from a function) as identifiers in plain SQL. You would need dynamic SQL in a plpgsql function for that.
But your example doesn't seem to need either. Do you want to copy rows from one table to another one? If so:
INSERT INTO production.layer_name
SELECT * FROM staging.layer_name

Related

Snowflake:Export data in multiple delimiter format

Requirement:
Need the file to be exported as below format, where gender, age, and interest are columns and value after : is data for that column. Can this be achieved while using Snowflake, if not is it possible to export data using Python
User1234^gender:male;age:18-24;interest:fishing
User2345^gender:female
User3456^age:35-44
User4567^gender:male;interest:fishing,boating
EDIT 1: Solution as given by #demircioglu
It displays as NULL values instead of other column values
Below the EMPLOYEES table data
When I ran below query
SELECT 'EMP_ID'||EMP_ID||'^'||'FIRST_NAME'||':'||FIRST_NAME||';'||'LAST_NAME'||':'||LAST_NAME FROM tempdw.EMPLOYEES ;
Create your SQL with the desired format and write it to a file
COPY INTO #~/stage_data
FROM
(
SELECT 'User'||User||'^'||'gender'||':'||gender||';'||'age'||':'||age||';'||'interest'||':'||interest FROM table
)
file_format = (TYPE=CSV compression='gzip')
File format here is not important because each line will be treated as a field because of your delimiter requirements
Edit:
CONCAT function (aliased with ||) returns NULL if you have a NULL value.
In order to eliminate NULLs you can use NVL2 function
So your SQL will have series of NVL2s
NVL2 checks the first parameter and if it's not NULL returns first expression, if it's NULL returns second expression
So for User column
'User'||User||'^' will turn into
NVL2(User,'User','')||NVL2(User,User,'')||NVL2(User,'^','')
P.S. I am leaving up to you to create the rest of the SQL, because Stackoverflow's function is to help find the solution, not spoon feed the solution.
No, I do not believe multiple delimiters like this are supported in Snowflake at this time. Multiple byte and multiple character delimiters are supported, but they will need to be specified as the same delimiter repeated for either record or line.
Yes, it may be possible to do some post-processing or use Python scripts to achieve this. Or even SQL transformative statements. This is not really my area of expertise so if someone has an example for you, I'll let them add to the discussion.

Use String parameter for RegEx in query

In my query (the database is a sql server) I use a RegEx for a select command like this:
SELECT * FROM test WHERE id LIKE '1[2,3]'
(This query is tested and returns the data I want)
I want to use a paramter for this RegEx. For that I definded the Paramter in iReport $P{id} as a string and the value is "1[2,3]".
In my query I use now this parameter like this:
SELECT * FROM test WHERE id LIKE $P{id}
As result I get a blank page. I think the problem is that the value of the parameter is defined with " ". But with ' ' I get a compiler error that the paramter isn't a string.
I hope someone can help me.
LIKE applies to text values, not to numeric values. Since id is numeric use something like this:
SELECT * FROM test WHERE id IN (12, 13)
with the parameter
SELECT * FROM test WHERE id IN ($P!{id_list})
and supply a comma separated list of ids for the parameter. The bang (!) makes sure that the parameter will be inserted as-is, without string delimiters.
Btw: LIKE (Transact-SQL) uses wildcards, not regex.
You can still use LIKE since there exists an implicit conversion from numeric types to text in T-SQL, but this will result in a (table or index) scan, where as the IN clause can take advantage of indexes.
The accepted answer works but it is using String replacement, read more about sql-injection, to understand why this is not good practice.
The correct way to execute this IN query in jasper report (using prepared statement) is:
SELECT * FROM test WHERE $X{IN, id, id_list}
For more information as the use of NOTIN, BETWEEN ecc. see JasperReports sample reference for query

sqlite why select like works and equals does not?

I have a problem with sqlite3 database, I execute the following queries
sqlite> select * from property where link like
"http://www.domain.com/huur/den-bosch/appartement-48118689-meester-spoermekerlaan-88/";
I get two rows
17|2014-11-03|Meester Spoermekerlaan
88|http://www.domain.com/huur/den-bosch/appartement-48118689-meester-spoermekerlaan-88/|5237
JZ|Den Bosch|€ 789|3|1
32|2014-11-03|Meester Spoermekerlaan
88|http://www.domain.com/huur/den-bosch/appartement-48118689-meester-spoermekerlaan-88/|5237
JZ|Den Bosch|€ 789|3|1
Then I execute the same query, but using the equality operator, like so
sqlite> select * from property where
link="http://www.domain.com/huur/den-bosch/appartement-48118689-meester-spoermekerlaan-88/";
sqlite> (<---- no results??)
I already found a similar answer to mine, however the issue is not the same, my fields are of datatype "text", as you can see here: https://stackoverflow.com/a/14823565/279147
sqlite> .schema property
CREATE TABLE property (id integer PRIMARY KEY AUTOINCREMENT UNIQUE,"date" text,address text,link text,postcode text,city text,price text,rooms text,page integer);
So does anybody have any idea why this would happen? here is my version information
root#s1:/# sqlite3 application.sqlite3
SQLite version 3.7.3
I had the same problem. This work around worked for me.
SELECT * from foo WHERE CAST(name AS BLOB) = CAST('bla' AS BLOB);
SQLite uses dynamic typing; it does not matter if the link column is declared as text or blob or fluffy bunnies.
LIKE automatically converts its parameters into strings, but the = operator does not.
Fix the program that writes the entries to the database to use the correct data type.
I had similar issue, in my case the point was, the like is not case sensitive, but the = operator is case sensitive.
This is because = is a literal string comparison so it would have to be exactly the same.
The like operator is looking for a matching pattern within the string and finds it.

Inserting an array column into the db in Yii

I needed to insert an array field into a database and I was pleased to notice that PostGreSQL had that functionality. But now I am not able to insert the data using the tables active record.
I have tried the below calls with no success
$active_record->array_column = $_array_of_values;
which gives me the exception
Exception Raised:CDbCommand failed to execute the SQL statement: SQLSTATE[22P02]: Invalid text representation: 7 ERROR: array value must start with "{" or dimension information
I have also tried this using
foreach($_array_of_values as $value){
$active_record->array_column[] = $value;
}
which tells me
Indirect modification of overloaded property FeatureRaw::$colors_names has no effect
Can anyone help me with this?
Thanks!
Data must be inserted in the form (text representation of an ARRAY):
INSERT INTO tbl (arr_col) VALUES ('{23,45}')
Or:
INSERT INTO tbl (arr_col) VALUES ('{foo,"bar, with comma"}')
So you need to enclose your array values in '{}' and separate them with comma ,. Use double quotes "" around text values that include a comma.
I listed more syntax variants to insert arrays in a related answer.
For those who also have same problem:
I didn't check the Yii1 behavior, but in Yii2 you simply can insert array as properly formed string as Erwin Brandstetter mentioned in his comment:
$activeRecord->arrayField = '{' . implode(',',$array_values) . '}';
Of course you need to make additional efforts when your $array_values has strings with commas, etc. And you still need to convert value back to array after you load ActiveRecord.
You can make these conversions in ActiveRecord's beforeSave() and afterLoad() and you will not need to convert values manually.
UPD. Recently I made a simple behavior for Yii2 to use array fields with ActiveRecord without manual field building: kossmoss/yii2-postgresql-array-field. It is more generalized way to solve the problem and I hope it will help. For those who use Yii1: you can investigate the package code and create your own solutuion compatible with your framework.

Is there any C SQLite API for quoting/escaping the name of a table?

It's impossible to sqlite3_bind_text a table name because sqlite3_prepare_v2 fails to prepare a statement such as:
SELECT * FROM ? ;
I presume the table name is needed to parse the statement, so the quoting needs to have happened before sqlite3_prepare_v2.
Is there something like a sqlite3_quote_tablename? Maybe it already exists under a name I can't recognize, but I can't find anything in the functions list.
SQLite will escape identifiers for you with the %w format in the https://www.sqlite.org/printf.html family of functions.
your proposed sqlite3_quote_tablename function could sanitize the input to prevent sql injection attacks. To do this it could parse the input to make sure it is a string literal. http://sqlite.org/lang_expr.html#litvalue
If a table name has invalid characters in it you can enclose the table name in double quotes, like this.
sqlite> create table "test table" (id);
sqlite> insert into "test table" values (1);
sqlite> select * from "test table";
id
----------
1
Of course you should avoid using invalid characters whenever possible. It complicates development and is almost always unnecessary (IMO the only time it is necessary is when you inherit a project that is already done this way and it's too big to change).
When using SQLite prepared statements with parameters the parameter: "specifies a placeholder in the expression for a literal value that is filled in at runtime"
Before executing any SQL statement, SQLite "compiles" the SQL string into a series of opcodes that are executed by an internal Virtual Machine. The table names and column names upon which the SQL statement operates are a necessary part of the compilation process.
You can use parameters to bind "values" to prepared statements like this:
SELECT * FROM FOO WHERE name=?;
And then call sqlite3_bind_text() to bind the string gavinbeatty to the already compiled statement. However, this architecture means that you cannot use parameters like this:
SELECT * FROM ? WHERE name=?; // Can't bind table name as a parameter
SELECT * FROM FOO WHERE ?=10; // Can't bind column name as a parameter
If SQLite doesn't accept table names as parameters, I don't think there is a solution for your problem...
Take into account that:
Parameters that are not assigned values using sqlite3_bind() are treated as NULL.
so in the case of your query, the table name would be NULL which of course is invalid.
I was looking for something like this too and couldn't find it either. In my case, the expected table names were always among a fixed set of tables (so those were easy to validate). The field names on the other hand weren't so I ended up filtering the string, pretty much removing everything that was not a letter, number, or underscore (I knew my fields would fit this parameters). That did the trick.

Resources