Oracle AUDSID equivalent in SQL Server 2012 - sql

What is the equivalent SQL Server 2012 code for this please ?
IF INSERTING THEN
:NEW.audsid:=SYS_CONTEXT('USERENV', 'SESSIONID');

Oracle and SQL Server handle triggers very differently. Oracle has the concept that a trigger affects only one row at a time. SQL Server doesn't. Instead, it uses a "table" inserted with the new rows.
So, your question has three parts:
What is the equivalent of INSERTED?
What is the equivalent of SYS_CONTEXT('USERENV', 'SESSIONID')?
What is the best way to do this in SQL Server?
Here is the answer to the first two questions:
if (exists (select 1 from inserted) and (not exists (select 1 from deleted))
update inserted
set audsid = ##SPID;
However, in most cases, you would just use the default keyword in the column definition:
audsid int default ##SPID
Much easier and a trigger isn't needed.

Related

Firebird trigger translated to MS SQL Server

I am converting a Firebird database to MS SQl Server. As there are multiple applications accessing the database, I really want to have the MS SQL Server act in as similar way as possible as to the Firebird database.
In Firebird it is declared as
CREATE TRIGGER CUSTOMER_BI FOR CUSTOMER
ACTIVE BEFORE INSERT POSITION 0
as
begin
if (new.cust_id is null) then
new.cust_id = gen_id(gen_cust_id,1);
end
So I have a Sequence (Generator in FB) called gen_cust_id
and my main objective is to fill the field cust_id with the nextvalue from the Sequence.
I am very much aware that the SQL Server offers me an autoinc field. This is not really what I am looking for here, as the frontend application(s) do this in various manners. Some of them get a sequence number first and may or may not commit the record. I do in this case just discard the generated sequence number.
Any help is highly appreciated.
Thanks in advance
Since the ANSI sequence was not implemented until SQL 2012, you should check out this article. I've used these suggestions to make use of sequences in SQL 2005 - 2008 for a while with great results.
http://blogs.msdn.com/b/sqlcat/archive/2006/04/10/sql-server-sequence-number.aspx
So, using option 2 (my preferred), you might have a trigger looking like below.
Note: this only works on a single row insert. If you want more than 1, you need to modify the example code in the link to give you ranges and do a set-based solution to address each null id row in the inserted "table".
CREATE TRIGGER dbo.CUSTOMER_BI
ON dbo.CUSTOMER INSTEAD OF INSERT
AS
BEGIN
DECLARE #sequence_id INT;
IF EXISTS(SELECT * FROM INSERTED WHERE cust_id IS NULL)
BEGIN
EXEC #sequence_id = dbo.GetNewSeqVal_Customer;
END
INSERT INTO CUSTOMER
(
cust_id,
<col list>
)
SELECT
ISNULL(cust_id, #sequence_id),
<col list>
FROM INSERTED;
END
the position 0 only matters if there is more than one trigger on the table and if there is the mssql side can merge them into 1

how to update table from linked server in sql server?

I have few tables I need to load from linked firebird server into SQL Server from time to time. I use statement like this:
SELECT * into dekr FROM OPENQUERY ( [PLINK] ,'select * from dekr' )
It takes a while since it's going over network etc, is there a way to update once created
table dekr only with changes since last time?
thanks

How to check column does not exist in SQL Server CE

If I run the following SQL in SQL Server CE,
alter table audit add new_key nvarchar(100) null
Can that be changed to check whether the column exists before trying to add it in the same SQL statement? I am aware you can do that quite easily in SQL Server, but SQL Server CE?
If you are looking for something like you can do with SQL server: IF NOT EXISTS (..., unfortunately, this is not possible with SQL Server Compact (the T-SQL IF is not supported). See SQL Reference (SQL Server Compact).
Based on this thread, you can do something like this:
select * from Information_SCHEMA.columns
where Table_name='audit' and column_name='new_key'
(ie no result = does not exist).
Also note that batch queries are not supported in SQL Server Compact at all. So you can't check if the column exists and add the column if needed in the same SQL statement.
Or if you are looking for a snippet that you can use with VB.NET or C#, take a look at this SO question: How can I determine whether a column exists in a SQL Server CE table with C#?
The easiest way would be to query information_schema and see if the column is in there.
IF NOT EXISTS(
SELECT * FROM information_schema.columns
WHERE Table_Schema = 'dbo'
AND Table_Name = 'audit'
AND Column_Name = 'new_key'
) BEGIN
alter table audit add new_key nvarchar(100) null
END

Oracle and Sybase compatibility for create table new_table as

I am trying to write an SQL query which needs to be compatible on both a Sybase and Oracle database. The query looks like the following :
SELECT *
INTO new_table
FROM other_table
This query is working great on a Sybase database but not on an Oracle one. I found the equivalent for Oracle :
CREATE table new_table AS
SELECT *
FROM other_table
Is there a way to write a third query that would do the same and that can be executed on a Sybase and on an Oracle database?
As you found, Oracle supports INTO but doesn't use it like Sybase/SQL Server do. Likewise, Sybase doesn't support Oracle's extension of the CREATE TABLE syntax.
The most reliable means of creating a table & importing data between the systems is to use two statements:
CREATE TABLE new_table (
...columns...
)
INSERT INTO new_table
SELECT *
FROM OLD_TABLE
Even then, syntax is different because Oracle requires each statement to be delimited by a semi-colon when TSQL doesn't.
Creating a table & importing all the data from another table is a red flag to me - This is not something you'd do in a stored procedure for a production system. TSQL and PLSQL are very different, so I'd expect separate scripts for DML changes.
There is no query that would do what you want. These environments are very different.
It is possible.
SELECT * INTO new_table FROM existing_table;
Thanks

informix check if table exists and then read the value

I have a table in informix (Version 11.50.UC4) called NextRecordID with just one column called id and it will have one row. What I want to do is copy this value into another table. But don't want my query to fail if this table does not exist. Something like
if table NextRecordID exists
then insert into sometable values ('NextRecordID', (select id from NextRecordID))
else insert into sometable values ('NextRecordID', 1)
I ended up using the below SQL query. Its not ANSI SQL but works the informix server I am using.
insert into sometable values ('NextRecordID',
select case (select 1 from systables where tabname='nextrecordid')
when 1 then (select nextid from nextrecordid)
else (select 1 from systables where tabname='systables') end
from systables where tabname='systables');
What is happening here is within insert query I get the value to be inserted by using select query. Now that select query is interesting. It uses case statement of Informix. I have written a select query to check if the table nextrecordid exists in systables and return 1 if it exists. If this query returns 1, I query the table nextrecordid for the value or else I wrote a query to return the default value 1. This work for me.
You should be able to do this by checking the systables table.
Thank you for including server version information - it makes answering your question easier.
You've not indicated which language(s) you are using.
Normally, though, you design a program to expect a certain schema (certain tables to be present), and then fail - preferably under control - if those tables are not present. Also, it is not clear whether you would get into problems because of repeated execution of the second INSERT statement. Nor is it clear when the NextRecordID table is updated - presumably, once the value has been used, it must be updated.
You should look at SERIAL (BIGSERIAL) and see whether that is appropriate for you.
You should also look at whether a SEQUENCE would be appropriate to use here - it certainly looks rather like it might be applicable.
As Adam Hughes points out, if you want to check whether the NextRecordID table is present in the database, you would look in the systables table. Be aware, though, that your search will need to be against an all lower-case name (nextrecordid).
Also, MODE ANSI databases complicate life - you have to worry about the table's owner (because there could be multiple tables called nextrecordid in a MODE ANSI database). Most likely, you don't have to worry about that - any more than you are likely to have to worry about delimited identifiers for table "someone"."NextRecordID" (which is a different table from someone.NextRecordID).