SQL Server: Inserting from various sources - sql

The simple version
What is the correct syntax of this?
INSERT INTO foo(IP, referer)
VALUES(SELECT bin FROM dbo.bar("foobar"),"www.foobar.com/test/")
I am getting syntax errors near 'SELECT' and ')'
The long version: I want to insert using a Function and a string (this is simplified, in reality there will be a few other values including datetime, ints, etc to insert along with the function result).
I have a function, itvfBinaryIPv4, which was set up to convert IPs to a binary(4) datatype to allow for easy indexing, I used this as a reference: Datatype for storing ip address in SQL Server.
So this is what I am trying to accomplish:
INSERT INTO foo (IP, referer)
VALUES(SELECT bin FROM dbo.itvfBinaryIPv4("192.65.68.201"), "www.foobar.com/test/")
However, I get syntax errors near 'SELECT' and ')'. What is the correct syntax to insert with function results and direct data?

It should be like this -
INSERT INTO foo (IP, referer)
SELECT bin, 'www.foobar.com/test/'
FROM dbo.itvfBinaryIPv4('192.65.68.201')
here assume dbo.itvfBinaryIPv4("192.65.68.201") is table valued function.

The INSERT command comes in two flavors:
(1) either you have all your values available, as literals or SQL Server variables - in that case, you can use the INSERT .. VALUES() approach:
INSERT INTO dbo.YourTable(Col1, Col2, ...., ColN)
VALUES(Value1, Value2, #Variable3, #Variable4, ...., ValueN)
Note: I would recommend to always explicitly specify the list of column to insert data into - that way, you won't have any nasty surprises if suddenly your table has an extra column, or if your tables has an IDENTITY or computed column. Yes - it's a tiny bit more work - once - but then you have your INSERT statement as solid as it can be and you won't have to constantly fiddle around with it if your table changes.
(2) if you don't have all your values as literals and/or variables, but instead you want to rely on another table, multiple tables, or views, to provide the values, then you can use the INSERT ... SELECT ... approach:
INSERT INTO dbo.YourTable(Col1, Col2, ...., ColN)
SELECT
SourceColumn1, SourceColumn2, #Variable3, #Variable4, ...., SourceColumnN
FROM
dbo.YourProvidingTableOrView
Here, you must define exactly as many items in the SELECT as your INSERT expects - and those can be columns from the table(s) (or view(s)), or those can be literals or variables. Again: explicitly provide the list of columns to insert into - see above.
You can use one or the other - but you cannot mix the two - you cannot use VALUES(...) and then have a SELECT query in the middle of your list of values - pick one of the two - stick with it.

Haven't checked it, but the correct syntax would be:
INSERT INTO foo (IP, referer)
SELECT bin, "www.foobar.com/test/" FROM dbo.itvfBinaryIPv4("192.65.68.201")

Related

Problem with the integer value in an SQL syntax: #1366 error

I was making a php website with some forms that let you make a form which let's you make an account, but for some reason when I was checking the SQL I was using inside phpmyadmin...
The SQL code it gave me an error that of
#1366 Incorrect integer value
Here is the SQL code I was checking:
INSERT INTO Users VALUES ('','$username','$password','0','empty')
The weird thing about this is the fact that the integer ID, which is in auto-increment, as I've learned it should be blank in the syntax like I've done (the ID column is the first one in my table)
When you are inserting rows into a table, the best practice is to always list the columns:
INSERT INTO Users (col1, col2, col3, col4)
VALUES ('', '$username', '$password', '0', 'empty');
I don't know what your column names are, so you have to fill them in.
If you are writing application code, another best practice is to use proper parameters rather than munging a query string with values.

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.

postgres varchar needs casting

I have 2 tables in 2 different schemas scha schb (e.g) and in scha I have a several tables that are all made of varchar as I had to format some data [it was part of the task]
now I have the same tables but with different types in schb.
The problem is this, Wherever I have a type which involves numbers (money, numerical, date), it's giving me an error to CAST.
Is there a way where I can CAST, without the need of copying one coloumn after another (copying it all in one go)
for example
INSERT INTO schb.customer
SELECT "col1", "col2" "col3 **(needs casting)**...."
FROM scha.customer
Thanks
A SELECT clause is not a list of columns, it is a list of expressions (which usually involve columns). A type cast is an expression so you can put them right into your SELECT. PostgreSQL supports two casting syntaxes:
CAST ( expression AS type )
expression::type
The first is standard SQL, the :: form is PostgreSQL-specific. If your schb.customer.col3 is (for example) numeric(5,2), then you'd say:
INSERT INTO schb.customer (col1, col2, col3)
SELECT col1, col2, cast(col3 as numeric(5,2))
FROM scha.customer
-- or
INSERT INTO schb.customer (col1, col2, col3)
SELECT col1, col2, col3::numeric(5,2)
FROM scha.customer
Note that I've included the column list in the INSERT as well. You don't have to do that but it is a good idea as you don't have to worry about the column order and it makes it easy to skip columns (or let columns assume their default values with explicitly telling them to).

SQL fixed-length insert statement formatter

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.

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" :-)