SQL fixed-length insert statement formatter - sql

Lets assume I have this long insert statement
insert into table1 (id, name, phone, very_long_col_name, ...)
values (1, 'very long name indeed...', '555-555-5555', 1, ...)
As you can see above, it gets hard to tell values from their column since their length is uneven
I'm looking for something (e.g. command line util) to format the above (not just SQL format) to this:
insert into table1 (id, name , phone , very_long_col_name, ...)
values (1 , 'very long name indeed...', '555-555-5555', 1 , ...)
This way I can see which value goes with which column easily
It can be a plugin to notepad++, a java utility, a plugin to an SQL IDE, what ever does the trick...
Prepared statements, T-SQL parameters, Hibernate, JPA etc is not an option right now

Not suggesting a plugin, but I mostly see this kind of thing formatted this way:
insert into table1
(
id,
name,
phone,
very_long_col_name,
...
)
values
(
1,
'very long name indeed...',
'555-555-5555',
1,
...
)
I find this more readable than scrolling through a very long line.

Have you considered the following alternative syntax?
INSERT INTO `table` SET
`id` = 1,
`name` = 'very long name indeed...',
`phone` = '555-555-5555',
`very_long_col_name` = 1,
`...` = '...'
;

Your better bet is to use SQL prepared statements. This lets you separate the SQL query syntax from your data, so you'd first prepare the statement:
$statement = mysqli_prepare("INSERT INTO `blah` (`id`,`phone`,`name`) VALUES(?,?,?)");
Then you bind the data to the statement:
$statement->bind('iss', 1234, "(555) 123-4567", "Kris");
I used PHP as an example, and the 'iss' in the above code says it's binding an Int and 2 strings in that order.

If the place that contains your SQL statement contains the DATA that you want to insert, then you are most probably doing something very, very, very wrong.
What do you want to achieve? Do you want to format the query, so that you can dump it in a pretty style for debugging purposes? Well, this is easy, just add strlen(some_string)-some_fixed_number number of whitespace at the appropriate places in your code. I can not suggest actual code here, because I do not know what language you use or what coding styles you prefer and so on...
But even if I wanted to, I do not see any value in this. You should separate SQL queries and the data that you use in your SQL queries (e.g. for inserting).
Building SQL query strings dynamically is out of fashion for some very good reasons (quoting, sql injection and so on...).
EDIT: If you want to format an SQL dump or some INSERT statements that prepare a database, then you can just use CSV formatted data. It is easier to read than SQL statements.

Variables?
insert into
table1 ( id, name, phone, very_long_col_name, ...)
values (#id, #name, #phone, #long_val, ...)
(obviously you need to declare and set / select these too)

In Oracle (since we can select from dual) I like to make these into insert into select from so I can alias the columns and make it easier to read:
insert into table1
(
id,
name,
phone,
very_long_col_name,
...
)
select 1 id,
'very long name indeed...' name,
'555-555-5555' phone,
1 very_long_col_name,
...
from dual;

A desired the same thing so I built this javascript tool:
SQL Insert Formatter
It does precisely what you ask and handles multiple statements. It is client-side only, so no need to worry about your data being uploaded.

Related

How do I work with table variables with multiple rows in SAP HANA DB?

In SQL sometimes it is easier and faster to use table variables.
I know I can't use insert to table var in HANA DB, but what would be the best practice to do something similar?
I tried using SELECT to populate the variable but I can't insert multiply rows.
Do I have to use temporary table instead?
I would like to have a table with some values I create, like the below example I use for SQL, such a way I can use it later in the query:
Declare #temp table(Group Int, Desc nvarchar(100))
insert into #temp (Group , Desc )
Values (1,'Desc 1'), (2,'Desc2 2'), (3,'Desc 3'), (4,'Desc 4'), (5,'Desc 5')
In HANA, I am able to create the variable, but not able to populate it with multiple rows :(
Is there any best way to do so?
Thank you so much.
The "UNION"-approach is one option to add records to the data that a table variable is pointing to.
Much better than this is to either use arrays to add, remove, and modify data and finally turn the arrays into table variables via the UNNEST function. This is an option that has been available for many years, even with HANA 1.
Alternatively, SAP HANA 2 (starting with SPS 03, I believe), offers additional SQLScript commands, to directly INSERT, UPDATE, and DELETE on table variables. The documentation covers this in "Modifying the Content of Table Variables".
Note, that this feature comes with a slightly different syntax for the DML commands.
As of SAP HANA 2 SPS 04, there is yet another syntax option provided for this:
"SQL DML Statements on Table Variables".
This one, finally, looks like "normal" SQL DML against table variables.
Given these options, the "union"-approach is the last option you should use in your coding.
For who else try to find about it, I found a "work around" that is to use the UNION ALL.
I add the first row, then I do a UNION on the table and ADD the second line, like below:
tempTable = Select 1 as "Group", 'Desc' as "Desc" FROM DUMMY;
tempTable = SELECT "Group", "Desc" FROM :AcctClassificacao UNION ALL Select 2 as "Group",
'Desc' as "Desc" FROM DUMMY ;
Select * from tempTable
In this case, I will have the result:
Group Desc
1 Desc
2 Desc
I don't know if this is the best way to do anyways.

Postgresql - INSERT INTO based on multiple SELECT

I intend to write a INSERT INTO request in Postgresql based on several SELECT but didn't succeed.
I have one table containing data I select (srctab), and another one where I insert data (dsttab).
Here is what I run :
INSERT INTO dsttab (dstfld1, dstfld2) WITH
t1 AS (
SELECT srcfld1
FROM srctab
WHERE srcfld3 ='foo'
),
t2 AS (
SELECT srcfld5
FROM srctab
WHERE srcfld6 ='bar'
) select srcfld1, srcfld5 from srctab;
Could you please help to make this work ? Thank you !
Note: I'm guessing about what you want to do here. My guess is that you want to insert a single row with the values from the CTEs (That's the WITH block.). Your query as written would insert a row into dsttab for every row in srctab, if it were valid syntax.
You don't really need a CTE here. CTEs should really only be used when you need to reference the same subquery more than once; that's what they exist for. (Occasionally, you can somewhat abuse them to control certain performance aspects in PostgreSQL, but that isn't the case in other DBs and is something to be avoided when possible anyway.)
Just put your queries in line:
INSERT INTO dsttab (dstfld1, dstfld2)
VALUES (
(SELECT srcfld1
FROM srctab
WHERE srcfld3 ='foo'),
(SELECT srcfld5
FROM srctab
WHERE srcfld6 ='bar')
);
The key point here is to surround the subqueries with parentheses.

How can I store sql statements in an oracle table?

We need to store a select statement in a table
select * from table where col = 'col'
But the single quotes messes the insert statement up.
Is it possible to do this somehow?
From Oracle 10G on there is an alternative to doubling up the single quotes:
insert into mytable (mycol) values (q'"select * from table where col = 'col'"');
I used a double-quote character ("), but you can specify a different one e.g.:
insert into mytable (mycol) values (q'#select * from table where col = 'col'#');
The syntax of the literal is:
q'<special character><your string><special character>'
It isn't obviously more readable in a small example like this, but it pays off with large quantities of text e.g.
insert into mytable (mycol) values (
q'"select empno, ename, 'Hello' message
from emp
where job = 'Manager'
and name like 'K%'"'
);
How are you performing the insert? If you are using any sort of provider on the front end, then it should format the string for you so that quotes aren't an issue.
Basically, create a parameterized query and assign the value of the SQL statement to the parameter class instance, and let the db layer take care of it for you.
you can either use two quotes '' to represent a single quote ' or (with 10g+) you can also use a new notation:
SQL> select ' ''foo'' ' txt from dual;
TXT
-------
'foo'
SQL> select q'$ 'bar' $' txt from dual;
TXT
-------
'bar'
If you are using a programming language such as JAVA or C#, you can use prepared (parametrized) statements to put your values in and retrieve them.
If you are in SQLPlus you can escape the apostrophe like this:
insert into my_sql_table (sql_command)
values ('select * from table where col = ''col''');
Single quotes are escaped by duplicating them:
INSERT INTO foo (sql) VALUES ('select * from table where col = ''col''')
However, most database libraries provide bind parameters so you don't need to care about these details:
INSERT INTO foo (sql) VALUES (:sql)
... and then you assign a value to :sql.
Don't store SQL statements in a database!!
Store SQL Views in a database. Put them in a schema if you have to make them cleaner. There is nothing good that will happen ever if you store SQL Statements in a database, short of logging this is categorically a bad idea.
Also if you're using 10g, and you must do this: do it right! Per the FAQ
Use the 10g Quoting mechanism:
Syntax
q'[QUOTE_CHAR]Text[QUOTE_CHAR]'
Make sure that the QUOTE_CHAR doesnt exist in the text.
SELECT q'{This is Orafaq's 'quoted' text field}' FROM DUAL;

Why do SQL INSERT and UPDATE Statements have Different Syntaxes?

While contemplating this question about a SQL INSERT statement, it occurred to me that the distinction in syntax between the two statements is largely artificial. That is, why can't we do:
INSERT INTO MyTable SET Field1=Value1, Field2=Value2, ...
or
UPDATE MyTable ( Field1, Field2 ...) VALUES ( Value1, Value2, ... )
WHERE some-key = some-value
Perhaps I'm missing something critical. But for those of us who have had to concatenate our SQL statements in the past, having comparable syntax for an INSERT and an UPDATE statement would have saved a significant amount of coding.
They're serving different grammatical functions. In an update you are specifying a filter that chooses a set of rows to which you will apply an update. And of course that syntax is shared with a SELECT query for the same purpose.
In an INSERT you are not choosing any rows, you are generating a new row which requires specifying a set of values.
In an UPDATE, the LHS=RHS stuff is specifying an expression which yields true or false (or maybe null :) and in an INSERT, the VALUES clause is about assignment of value. So while they are superficially similar, they are semantically quite different, imho. Although I have written a SQL parser, so that may influence my views. :)
SQL Server 2008 has introduced UPSERT functionality via the MERGE command. This is the logical equivalent of
IF FOUND THEN
UPDATE
ELSE
INSERT
I believe this is so that you may make an insert statement without being explicit about the values. If you are putting a value in every single column in the table you can write:
insert into my_table values ("value1", 2);
instead of:
insert into my_table (column1, column2) values ("value1", 2);
When importing and exporting entire (large) databases, this is invaluable for cutting down file size and processing time. Nowadays, with binary snapshots and the like, it may be "less invaluable" :-)

SQL: Use the same string for both INSERT and UPDATE?

The INSERT syntax I've been using is this
INSERT INTO TableName VALUES (...)
The UPDATE syntax I've been using is
UPDATE TableName SET ColumnName=Value WHERE ...
So in all my code, I have to generate 2 strings, which would result in something like this
insertStr = "(27, 'John Brown', 102)";
updateStr = "ID=27, Name='John Brown', ItemID=102";
and then use them separately
"UPDATE TableName SET " + updateStr + " WHERE ID=27 " +
"IF ##ROWCOUNT=0 "+
"INSERT INTO TableName VALUES (" + insertStr + ")"
It starts bothering me when I am working with tables with like 30 columns.
Can't we generate just one string to use on both INSERT and UPDATE?
eg. using insertStr above on UPDATE statement or updateStr on INSERT statement, or a whole new way?
I think you need a whole new approach. You are open to SQL Injection. Provide us with some sample code as to how you are getting your data inputs and sending the statements to the database.
alt text http://goose.ycp.edu/~weddins/440/S09%20IFS440%20Bobby%20Drop%20Tables.PNG
As far as I'm aware, what you're describing isn't possible in ANSI SQL, or any extension of it that I know. However, I'm mostly familiar with MySQL, and it likely depends completely upon what RDBMS you're using. For example, MySQL has "INSERT ... ON DUPLICATE KEY UPDATE ... " syntax, which is similar to what you've posted there, and combines an INSERT query with an UPDATE query. The upside is that you are combining two possible operations into a single query, however, the INSERT and UPDATE portions of the query are admittedly different.
Generally, this kind of thing can be abstracted away with an ORM layer in your application. As far as raw SQL goes, I'd be interested in any syntax that worked the way you describe.
Some DBMS' have an extension to do this but why don't you just provide a function to do it for you? We've actually done this before.
I'm not sure what language you're using but it's probably got associative arrays where you can wrote something like:
pk{"ID"} = "27"
val{"Name"} = "'John Brown'"
val{"ItemID"} = "102"
upsert ("MyTable", pk, val)
and, if it doesn't have associative arrays, you can emulate them with multiple integer-based arrays of strings.
In our upsert() function, we just constructed a string (update, then insert if the update failed) and passed it to our DBMS. We kept the primary keys separate from our other fields since that made construction of the update statement a lot easier (primary key columns went in the where clause, other columns were just set).
The result of the calls above would result in the following SQL (we had a different check for failed update but I've put your ##rowcount in for this example):
update MyTable set
Name = 'John Brown',
ItemID = 102
where ID = 27
if ##rowcount=0
insert into MyTable (ID, Name, ItemID) values (
27,
'John Brown',
102
)
That's one solution which worked well for us. No doubt there are others.
Well, how about no statements? You might want to look into an ORM to handle this for you...
Some databases have proprietary extensions that do exactly this.
I agree that the syntax of INSERT and UPDATE could be more consistent, but this is just a fact of life now -- it ain't gonna change now. For many scenarios, the best option is your "whole new way": use an object-relational mapping library (or even a weak-tea layer like .NET DataSets) to abstract away the differences, and stop worrying about the low-level SQL syntax. Not a viable option for every application, of course, but it would allow you to just construct or update an object, call a Save method and have the library figure out the SQL syntax for you.
If you think about it, INSERT and UPDATE are exactly the same thing. They map field names to values, except the UPDATE has a filter.
By creating an associative array, where the key is the field name and the value is the value you want to assign to the field, you have your mapping. You just need to convert it to a the proper string format depending on INSERT or UPDATE.
You just need to create a function that will handle the conversion based on the parameters given.
SQL Server 2008:
MERGE dbo.MyTable AS T
USING
(SELECT
#mykey AS MyKey
#myval AS MyVal
) AS S
ON (T.MyKey = S.MyKey)
WHEN MATCHED THEN
UPDATE SET
T.MyVal = S.MyVal
WHEN NOT MATCHED THEN
INSERT (MyKey, MyVal)
VALUES (S.MyKey, S.MyVal)
MySQL:
INSERT (MyKey, MyVal)
INTO MyTable
VALUES({$myKey}, {$myVal})
ON DUPLICATE KEY UPDATE myVal = {$myVal}