Can someone help in converting this SQL Server "update statement" to Oracle - sql-server

update a
set a.col1 = 1,
a.col2 = 'abc' + CAST(b.colID AS VARCHAR(3))
from #abc a
cross apply
(select top 1 x.col3, x.colID1
from #xyz x
where (x.col3 = a.col3 and
x.colID1 IN (0, 9, 8))) b
Table abc and xyz are temp tables that's why the '#'.
Need to convert the above script to Oracle

below link could help you what you want to achive...
https://oracle-base.com/articles/18c/private-temporary-tables-18c

Related

SQL Server job gets stuck occasionally

I found my SQL Server job gets stuck occasionally, about once every two months. Since I am not from DBA background, I need some to help to rectify the issue.
So far, I have tried to pinpoint the issue by checking the activity monitor. I found the issue is caused by one of my stored procedures which it will create a temp table to collect data, then the data will be inserted into one of my transaction tables. This table have 400 millions of records.
Whenever this issue occur, I stop the job and:
I rerun the job, the stored procedure can complete
I execute the stored procedure manually, the stored procedure completes
I implemented the SP_BlitzCache, and execute it. I can see it suggest DBCC FREEPROCCACHE (0x0...) on the stored procedure.
CREATE TABLE #dtResult
(
RunningNumber INTEGER,
, AlphaID BIGINT
, BetaID BIGINT
, Content varchar(100)
, X varchar(10)
, Y varchar(10)
)
INSERT INTO #dtResult ( RunningNumber, ...)
SELECT RowId AS RunningNumber,
...
FROM
...
/*** Based on activity monitor, the highest CPU caused by this statement ***/
INSERT INTO tblTransaction ( ... )
SELECT DISTINCT
RES.AlphaID
, b.UnitId
, RES.BetaID
, CASE WHEN RES.BinData IS NULL THEN [dbo].[fnGetCode](B.Data, RES.X, RES.Y) ELSE RES.Content END
, CONVERT(DATETIME, SUBSTRING(RES.Timestamp, 1, 4) + '-' + SUBSTRING(RES.Timestamp, 5, 2) + '-' + SUBSTRING(RES.Timestamp, 7, 2) + ' ' + SUBSTRING(RES.Timestamp, 9, 2) + ':' + SUBSTRING(RES.Timestamp, 11, 2) + ':' + SUBSTRING(RES.Timestamp, 13, 2) + '.' + SUBSTRING(RES.Timestamp, 15, 3), 121)
FROM
#dtResult RES
INNER JOIN
tblA a with(nolock) ON RES.AlphaID = a.AlphaID
INNER JOIN
tblB b with(nolock) ON a.UnitId = b.UnitId AND CAST(RES.X AS INTEGER) = b.X AND CAST(RES.Y AS INTEGER) = b.Y
INNER JOIN
tblC c with(nolock) ON RES.BetaID = c.BetaID
LEFT OUTER JOIN
tblTransaction t with(nolock) ON RES.AlphaID = t.AlphaID AND RES.BetaID = t.BetaID AND t.UnitId = b.UnitId
WHERE
t.BetaID IS NULL
/* FUNCTION */
CREATE FUNCTION [dbo].[fnGetCode]
(
#Data VARCHAR(MAX),
#SearchX INT,
#SearchY INT
)
RETURNS CHAR(4)
WITH ENCRYPTION
AS
BEGIN
DECLARE #SearchResult CHAR(4)
DECLARE #Pos INT
SET #Pos = (#SearchY * #SearchX) + 1
SET #SearchResult = CONVERT(char(1),SUBSTRING(#Data,#Pos,1), 1)
RETURN #SearchResult
END

How to export Sybase table contents to a text file?

I want to export the tables with contents from a Sybase database to a text file. I am using Sybase ASE 15.5 and that can't be changed/upgraded.
I have tried using sp_tables and different Select commands, but they don't give the result I'm looking for.
The output format I'm looking for is something like this:
FIRST_TABLE
Column_1 Column_2 Column_3
Roger Male 51
Anne Female 46
SECOND_TABLE
Column_1 Column_2 Column_3
BMW German Car
Schwinn American Bicycles
etc.etc.
Create a view that generates the output you want and use bcp to copy the data from the view.
Consider the following table, view and data:
create table t1 (
k int not null,
v varchar(255) null)
go
create view v1 as
select
'k' as k,
'v' as v
union all
select
convert(varchar, k),
v
from
t1
go
insert into t1 (k, v) values (1, 'Line_1')
insert into t1 (k, v) values (2, 'Line_2')
insert into t1 (k, v) values (3, 'Line_3')
go
Check the data returned from the view, notice the column names are in the result set. They need to here. Ideally you would query against syscolumns, but there is no pivot statement in ASE, so you need to know the names in advance :-(
select * from v1
go
k v
1 Line_1
2 Line_2
3 Line_3
(4 rows affected)
Now copy the data from the view into the text file:
$ bcp <db_name>..v1 out v1.txt -c -U login_name -S server_name
Password:
Starting copy...
4 rows copied.
Network packet size (bytes): 4096
Clock Time (ms.) Total : 1 Average : (4000.0 rows per sec.)
$ cat v1.txt
k v
1 Line_1
2 Line_2
3 Line_3
Without using BCP
declare cur cursor for
select sc.name from sysobjects so, syscolumns sc
where so.id = sc.id and so.name = 'FIRST_TABLE'
order by sc.colid
go
declare #l_name varchar(30), #l_sql varchar(2000)
begin
open cur
fetch cur into #l_name
while ##sqlstatus = 0
begin
set #l_sql = #l_sql + '''' + #l_name + ''','
fetch cur into #l_name
end
close cur
deallocate cur
set #l_sql = 'select ' + substring(#l_sql,1,len(#l_sql)-1)
set #l_sql = #l_sql + ' union all select * from FIRST_TABLE'
exec (#l_sql)
end
go

How to get names of the 'only updated columns' in a trigger?

I would like to print the names of the 'only updated columns' from inside my trigger.
For instance, my table has three columns - ColA, ColB and ColC.
If I update only ColB, my trigger should print only ColB.
If I update only ColA & ColC, my trigger should print only ColA & ColC.
May I know how to achieve this in a shorter and cleaner way please?
This site helped me - https://ask.sqlservercentral.com/questions/44368/columns-updated-not-returning-the-column-name.html
create table Sample1
(
a varchar(10),
b varchar(10),
c varchar(10)
);
alter trigger TR_Sample1_Update ON Sample1 for update as
DECLARE #modifiedColumns nvarchar(max)
SET #modifiedColumns = STUFF((SELECT ',' + name FROM sys.columns WHERE object_id = OBJECT_ID('Sample1') AND COLUMNS_UPDATED() & (POWER(2, column_id - 1)) <> 0 FOR XML PATH('')), 1, 1, '')
PRINT #modifiedColumns
go
update Sample1 set a = 1 where a = 1
update Sample1 set b = 4 where a = 1
update Sample1 set c = 5 where a = 1
update Sample1 set a = 1, c = 5 where a = 1
update Sample1 set a = 1, b = 4, c = 5 where a = 1
It worked. Please try it in LinqPad.
Personally I hate triggers and try to avoid them most of the time ;-)
However, the only way I know of is with the function COLUMNS_UPDATED() inside your trigger code. See also examples like: https://sites.google.com/site/bugsarewelcome/home/columns_updated

Update table variable from the same table variable?

I've got a table variable (#t_var) like this:
[RSIN] [Grp]
S-000001 1
S-000002 2
S-000003 1
C-000002 null
C-000003 null
I need to set [Grp] for "C"-types based on [Grp] for "S"-types with respective right parts. In the end I should get like this:
[RSIN] [Grp]
S-000001 1
S-000002 2
S-000003 1
C-000002 2
C-000003 1
The most obvious way I was trying to do:
UPDATE #t_var
SET [Grp] = B.[Grp]
FROM #t_var A
LEFT JOIN #t_var B
ON 'C'+RIGHT(A.[RSIN], 7) = B.[RSIN]
WHERE LEFT(A.[RSIN],1) = 'S'
But Management Studio tell me something about it can't distinct which #t_var to use. This construct works fine when we talk about physical tables, but refuses to work when it comes to table variables.
Is there any elegant workaround but to create duplicate table variable like #t_var2 and using it in join?
declare #t_var table (RSIN char(8), Grp int);
insert #t_var
values
('S-000001', 1),
('S-000002', 2),
('S-000003', 1),
('C-000002', null),
('C-000003', null)
;with x as (
select b.rsin, a.grp, b.grp as prev
from #t_var a
inner join #t_var b on 'c'+right(a.[rsin], 7) = b.[rsin]
where left(a.[rsin],1) = 's'
)
update x
set prev = grp
select * from #t_var
Table names and column names can't be dynamic. They need to stay static
You need to use Dynamic SQL here
Read more about
Building Dynamic SQL In a Stored Procedure
The Curse and Blessings of Dynamic SQL
sp_executesql
Hoe this helps
UPDATE #t_var
SET [Grp] = CASE WHEN LEFT([RSIN], 1) = 'C'
AND RIGHT([RSIN], 1) = '2'
THEN 2
WHEN LEFT([RSIN], 1) = 'C'
AND ( RIGHT([RSIN], 1) = '1'
OR
RIGHT([RSIN], 1) = '3' )
THEN 1
END

How to perform split operation on strings and attach to specific ids using SQL SERVER 2000(Without cursor)?

I have a table wuth the folowing structure
PickupPointCode LocationCode ClientCode
1 LOC1 Client1/Client2
2 LOC2 Client3/Client4/Client5
3 LOC3 Client6
The desired output being
PickupPointCode LocationCode ClientCode
1 LOC1 Client1
1 LOC1 Client2
2 LOC2 Client3
2 LOC2 Client4
2 LOC2 Client5
3 LOC3 Client6
Using SQL serevr 2005 I wrote the below query to get this done
;WITH cte AS (
SELECT
PickupPointCode
,LocationCode
,CAST('<i>' + REPLACE(ClientCode, '/', '</i><i>') + '</i>' AS XML) AS ClientCodes
FROM <TABLE NAME>)
SELECT
PickupPointCode
,LocationCode
,x.i.value('.', 'VARCHAR(MAX)') AS ClientCode
FROM cte
CROSS APPLY ClientCodes.nodes('//i') x(i)
But now I have to do the same thing using SQL SERVER 2000. How can I perform the same?
Thanks
The basic idea is to multiply each row as many times as there are CLIENTs. Then, extract the appropriate part of the string.
Have a look at some example queries that work on SQL2005+ here.
You will need to work with an extra table that contains sequential numbers in SQL2000.
CREATE TABLE dbo.Numbers
(
N INT NOT NULL PRIMARY KEY
);
GO
DECLARE #rows AS INT;
SET #rows = 1;
INSERT INTO dbo.Numbers VALUES(1);
WHILE(#rows <= 1000)
BEGIN
INSERT INTO dbo.Numbers SELECT N + #rows FROM dbo.Numbers;
SET #rows = #rows * 2;
END
This is the numbers table you can join onto. And below is the query that should work on SQL 2000.
SELECT PickupPointCode, LocationCode,
SUBSTRING(ClientCode, Numbers.N,
CHARINDEX('/', ClientCode + '/', Numbers.N) - Numbers.N) AS ClientCode
FROM <TABLE_NAME>
JOIN Numbers ON Numbers.N <= DATALENGTH(ClientCode) + 1
AND SUBSTRING('/' + ClientCode, Numbers.N, 1) = '/'

Resources