Upsert (update or insert) in Sybase ASE? - sql

I'm writing an application to move data from Oracle to Sybase and need to perform update / insert operations. In Oracle, I'd use MERGE INTO, but it doesn't seem to be available in Sybase (not in ASE, anyway). I know this can be done with multiple statements, but for a couple of reasons, I'm really trying to get this into a single statement.
Any suggestions?

ASE 15.7 has this feature.
Find the docs here:
http://infocenter.sybase.com/help/topic/com.sybase.infocenter.dc36272.1570/html/commands/commands84.htm

Sybase and DB2 are very IEC/ISO/ANSI SQL Standrd-compliant. MS a little less so.
Oracle is not very Standard-compliant at all (despite what the glossies say). More important, due to it limitations, the method they use to overcome them is to introduce Extensions to SQL (which are not required for the others DBMS, which do not have the limitations). Nice way of making sure that customers do not migrate away.
So the best advice for you is to learn the SQL Standard way of doing whatever you were doing on the Oracle side. And second (not first) learn about Sybases or DB2s (or whatever) Extensions.
"MERGE" and "UPSERT" do not exist in SQL, they exist in Oracle only. The bottom line is, you have to UPDATE and INSERT in two separate operations.
In SQL, UPDATE and INSERT apply to a single table; you may have quite complex FROM clauses.
For "MERGE", that is simply an:
INSERT target ( column_list ) -- we do have defaults
SELECT ( column_list )
FROM source
WHERE primary_key NOT IN ( SELECT primary_key FROM target )
Update is simply the complement:
UPDATE target SET ( target_column = source_column, ... )
FROM source
WHERE primary_key IN ( SELECT primary_key FROM target )
In the UPDATE it is easy to merge the WHERE conditions and eliminate the Subquery (I am showing it to you for explanation).
As I understand it, Oracle is abyssmal at executing Subqueries (Standard SQL). Which is why they have all these non-Standard "MERGE", etc., the purpose of which is to avoid the Standard Subquery syntax, which every other DBMS performs with ease.

unfortunately, it is impossible to insert and update a table in one statement without using MERGE. which btw does exist in SQL as of SQL:2008, according to this article anyway, and supported by almost all major databases, except Sybase ASE and PostgreSQL.

Merge exists in SAP ASE 15.7 upwards, as mentioned here and here
Replace / Upsert exists in SAP ASE 16.0 and up.
You'll need to update to access them.

Maybe it could work. Tested in ASA9.
insert into my_table (columns) on existing update values (values);

May be you could try to fake it with INSERT INTO and/or UPDATE FROM with some sub-queries but it will not be as convenient as Oracle does.
You wanna do this into code or data warehouse ? because you could also encapsulate all the SQL into a stored procedure if you want to hide the complexity of the queries.

Related

Are There Any RDBMS That Can Update or Insert In One Statement?

If I have a table like this:
ID FirstName LastName Address
-- --------- -------- -------
I want to update info when there is an existing ID or insert a new row when the ID does not already exist.
Can this be done in one statement or do I have to check for the existance of the ID and then either insert or update?
Yes. There are three methods that come to mind:
merge is the most common method. SQL Server, Oracle, DB2, and Teradata support this. Refer to the appropriate documentation. Note that the exact merge syntax may vary from database to database.
on duplicate key update is a method used by (older versions of) MySQL and MariaDB. Refer to the appropriate documentation.
Postgres and SQLite supports conflict resolution via the on conflict clause in insert statements. That said, many databases are based older versions of Postgres, so not all derived databases support on conflict.
(I apologize for databases not listed. This is off the top of my head.)
If a database supports this functionality, then one of these three methods is probably used. You can always use transactions to get similar effects using multiple statements.

what kind of statement is SELECT INTO,is it DDL or DML?

there is an specify remark for SELECT INTO clause,that I don't know it?is SELECT INTO a DDL or DML?I will appreciate if explain me that specify remark?
thanks
I would say DML as DDL is used to define the database structure, and DML for managing data.
Select into is not different from a insert into, I belive.
Both. It's DDL because it changes the catalog. It's DML because SELECT is DML.
The Wikipedia article on Data manipulation language says (highlighting is mine):
The SQL-data change statements are a subset of the SQL-data statements; this also contains the SELECT query statement, which strictly speaking is part of the DQL, not the DML. In common practice though, this distinction is not made and SELECT is widely considered to be part of DML, so the DML consists of all SQL-data statements, not only the SQL-data change statements. The SELECT ... INTO ... form combines both selection and manipulation, and thus is strictly considered to be DML because it manipulates (i.e. modifies) data.
I Think Basically Select into is a combination query provided by microsoft from Sql server 2008 onwards to backeup data to a table, here we using DDL for creating table and DML for insertion at the definition level of SELECT INTO.

Multiple inserts in one SQL query

DB: SQL server
I am using the below construct for inserting multiple records into a table. I am receiving the data (to be inserted) from other DB.
Insert into table1
select '1','2' UNION ALL
select '3','4' UNION ALL
select '5','6';
would there be any other chance in doing inserts in less turn around time. Its also been executed as a web request. I guess bulk insert would not fit here, as I don't have the data in a file to do a bulk insert.
Any suggestions please..
If the source database is also a SQL Server, you could add a linked server and:
insert table1 select * from linkedserver.dbname.dbo.table1
If you're inserting from .NET code, the fastest way to insert multiple rows is SqlBulkCopy. SqlBulkCopy does require DBO rights.
That is actually the best multiple insert I have ever seen. Just be careful to SQL injections, always use CommandParameters in ASP.NET or use mysql_real_escape in MySQL.
I looked into this recently, coming from MySQL and expecting the syntax from cularis' answer, but after some searching all I could find is the syntax you posted in your answer.
Edit: Looks like cularis removed his answer, he was talking about the INSERT INTO x VALUES (1, 2), (3, 4); syntax.
If you are using SQL Server 2008 and stored procedures, you could always make use of table valued parameters:
http://www.sqlteam.com/article/sql-server-2008-table-valued-parameters
It then becomes an INSERT INTO ... SELECT * FROM ...
This would help against injection problems. Not sure if this is possible with parameterised SQL.

creating a table only if it's not existing with ANSI sql

I am trying to dynamically create a SQL table only if it's not already existing. I have seen many solutions on the internet but they usually rely on a specific database, while I'm trying to find the most generic solution.
I was thinking of always running the CREATE command and then assuming that if it fails then the table exist and I can start inserting data into it. I can't see any flaw in this reasoning (not counting performance issues), but I might be wrong.
Is this an acceptable method?
Can you suggest other methods which are database independent, or that use ANSI SQL that all RDBMS would accept?
if there is a table - say - EMP, does that really imply that it is the same EMP that you are expecting?
Either query the appropriate data dictionary for the table structure, or fill your code with a ton of error checking and conditional logic...
INFORMATION_SCHEMA is part of the ANSI SQL Standard, so you should be able to:
IF NOT EXISTS(SELECT NULL FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'YourTable')
CREATE TABLE...
what about: create table if not exists

In SQL, is 'FROM' in 'DELETE FROM' optional if you plan to use 'WHERE'?

I'm new to SQL. We have some code that should work on SQL Server 2005/2008, Oracle 10 as well as Sybase.
I was writing a script to try to figure out which tables a given stored procedure modifies (but does not drop), e.g insert, update and delete.
The delete one turned out being puzzling - sometimes I see statements like:
delete phone_book where ...
as opposed to:
delete from phone_book where ...
So ... is the from keyword truly optional in this case? Does this cause any problems? Is it just a bad style, or does it not matter?
I have not found a reference to T-SQL that would make from optional. I suppose that this is what would unify all 3 vendors I mentioned above.
Questions/comments/links are welcomed (or is it welcome?).
At this place the FROM is optional (SQL Server, Oracle, Sybase).
However, there are subtle differences: Oracle for instance allows assigning an alias to the table name, where SQL Server doesn't; and other things are also a little bit different.
Also note that your FROM sample is differnet from the following where it is mandatory:
DELETE phone_book FROM some_table WHERE ...
Short Answer: Luceros answer is correct: it is optional
I have to maintain sql and adapt it between sql-server and Oracle. Here are some rules:
Write Scripts manually, don't use generated code.
Always use INSERT INTO.
Always DELETE -- without FROM.
Do not use " - quoted identifier.
Remove all [ ] and dbo. (Schema names)
Attention when you see DELETE ... FROM ...
Attention when you see UPDATE ... FROM ...
ORACLE Select statements need a from clause you can use from DUAL
OK you can script your objects and edit them in a standard way
USE [Current_DB] -- you don't want a reference to your test database go into production script
SET ANSI_NULLS ON -- decide once which settings to use -- don't switch on and off
SET QUOTED_IDENTIFIER ON -- quoted identifiers are case-sensitive.
INSERT INTO is required by Oracle.
That is my personal style don't use optional keyword, learn the defaults
You have to quote an identifier, if you use one of ORACLES reserved keywords as column name, we entered that pitfall and in the long run it would have been better to rename the column on the sql-Server side.
Oracle doesn't use these.
Oracle doesn't support this syntax.
Oracle doesn't support this syntax.
From the Microsoft SQL Server documentation, FROM is optional.
from is optional in delete from in those three DBMSes but it is mandatory according to the SQL standard. I would always use delete from to ease the migration of SQL code from one DBMS to another.
In SQL Server, FROM of DELETE FROM is optional and DELETE without FROM is not SQL standard while DELETE FROM is SQL standard.
I experimented DELETE FROM and DELETE without FROM on SQL Server, MySQL, PostgreSQL and SQLite as shown below:
Database
DELETE FROM
DELETE
SQL Server
Possible
Possible
MySQL
Possible
Impossible
PostgreSQL
Possible
Impossible
SQLite
Possible
Impossible
In addition, I also experimented INSERT INTO and INSERT without INTO on SQL Server, MySQL, PostgreSQL and SQLite as shown below.
Database
INSERT INTO
INSERT
SQL Server
Possible
Possible
MySQL
Possible
Possible
PostgreSQL
Possible
Impossible
SQLite
Possible
Impossible