UPDATING a section of string for column - sql

We have the following:
create table #a_table
(names char(10))
insert into #a_table
values
('A;B;C;'),
('B;C;D;'),
('A;B;C;E;'),
('A;C;'),
('A;B;'),
('A;'),
('A;C;E;');
How do we update the table and change every instance of C; with X;Y;
So
A;B;C; would become A;B;X;Y;
A;C;E; would become A;X;Y;E;
etc.
EDIT
A standard ANSI approach that is compatible on SQL-server would be prefereable.

This all depends on which database you're actually using. In MSSQL Server You can use the SQL replace function
update #a_table set names = replace(names, 'C;', 'X;Y;')
Other databases have similar functions (such as the MySQL one here)

Related

SQL - adding new column withouth effecting existing scripts

We have a table on the SQL Server 2008 which gets populated by various stored procedures. The problem is that the authors of these stored procedures used some poor choice in code and populated this table using the following syntax:
INSERT INTO persistant_table
SELECT *
FROM #temp_table_with_data
Basically they would create a #temp_table_with_data in the script and the columns would be in the same order and with the same name as they are in the persistant_table.
Now I need to add another column to this persistant_table, but if I do that, I will break all the stored procedures.
Is there a way for me to add a column to this table without breaking all the stored procedures? (In the long run, we will change the stored procedures).
Thank you
No I think.select * will pick all columns and column number should match.
I don't think it's big effort to change the line to have particular columns only or select statement to have default value for column or null and then * to store into columns sequentially. But at least 1 line to be changed
The "ALTER TABLE" is a SQL statement that allows you to make datatype changes to a database table (i.e. change datatype as well as Size columns from an existing table).
ALTER TABLE TableName ALTER COLUMN ColumnName NVARCHAR(200)
You cannot do it without affecting old scripts. This is why 'SELECT *' is not good practice. You'd better create new scripts with explicit column names like
SELECT column1, column2 ....

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

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

In T-SQL, how to insert a new row with all values set by default?

In Microsoft SQL database, I have a table where every column have default values (either fixed values or stuff like identity or getdate()).
I am trying to write an SQL statement which will insert a new row in which every cell will have a default value.
Neither
insert into MySchema.MyTable
nor
insert into MySchema.MyTable () values ()
are valid syntax.
So is it possible to insert a new row without specifying any value?
insert into foo DEFAULT VALUES
Standard SQL
INSERT INTO tablename VALUES ( DEFAULT, DEFAULT, DEFAULT... )
When the DEFAULT reserved keyword is used in place of an actual value, it means the default value of the field. This allows you to specify some columns but not others.
The syntax is part of the SQL standard, and works on most databases since 2005:
MS SQL TSQL - 2005+
Oracle PL/SQL - 10g r2+
MySQL - 5.5+/4.1+
PostgreSQL - 8.0+
DB2, H2, etc.
(Simple databases, such as SQLite or Access, tends to not support these "new" or "advanced" syntax.)
Non-Standard
INSERT INTO tablename DEFAULT VALUES
This will insert a new row populating everything with default values.
As far as I know this syntax is non-standard, and few databases support it - I know only MS SQL and PostgreSQL.
While I personally don't use it, I can see the use case and it may be made standard like DEFAULT fields in the future.

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).