Teradata: How to create views dynamically from database tables - sql

I am using Teradata BTEQ version 15.00. I have the following SQL code. The dynamical SQL is almost there, but the formet is a little off.
.Export Report File = CViews.sql
.Rtitle ''
.Foldline on
.Format Off
.set heading '';
.set heading off;
.set UNDERLINE OFF;
.Omit On 4,5
Select
CASE When ColNo = 1
THEN 'Replace View
$view_db_name.VW_'||Tbl.Tablename||' As locking row for access
Select ('
Else '' END (Title '')
, Cols.Columnname (Title '')
, CASE WHEN RevColNo = 1 THEN ')
From $db_name.'||Tbl.Tablename||';'
Else '' END (Title '')
, Row_Number () Over(Partition By Tbl.Tablename
Order By Cols.ColumnId) As ColNo
, Row_Number () Over(Partition By Tbl.Tablename
Order By Cols.ColumnId Desc) As RevColNo
From DBC.Tables Tbl
Join DBC.Columns Cols
On Tbl.Databasename = Cols.Databasename
And Tbl.Tablename = Cols.TableName
Where Tbl.Databasename = '$db_name'
And Tbl.Tablekind = 'T'
Order By Tbl.Tablename, ColNo
;
.Export Reset
.Run File CViews.sql
Here are the results, but "locking row for access" was cut off, so i got errors when compiling SQL.
Replace View VIEWS_TEST.VW_LOCATION As loc
ID
LOC_TYPE_ID
NAME
LATITUDE
LONGITUDE
ADDR1
ADDR2
CITY
STATE
COUNTRY
) From TABLES_TEST.LOCATION ;
You can see that the "As Loc" was cut off, so i got the following errors:
*** Failure 3707 Syntax error, expected something like a 'SELECT' keyword o
r a 'LOCK' keyword or '(' or a 'TRANSACTIONTIME' keyword between the 'As' key word and the word 'loc'.
Statement# 1, Info =81
*** Total elapsed time was 1 second.
I tried different ways try to make it work, but failed.
Any suggestions?

.Export Report File = CViews.sql
.set width 200
.Rtitle ''
.Foldline on
.Format Off
.set heading '';
.set heading off;
.set UNDERLINE OFF;
.Omit On 4,5
Select
CASE When ColNo = 1
THEN 'Replace View
$view_db_name.VW_'||Tbl.Tablename||' As locking row for access
Select ('
Else '' END (Title '')
, Cols.Columnname (Title '')
, CASE WHEN RevColNo = 1 THEN ')
From $db_name.'||Tbl.Tablename||';'
Else '' END (Title '')
, Row_Number () Over(Partition By Tbl.Tablename
Order By Cols.ColumnId) As ColNo
, Row_Number () Over(Partition By Tbl.Tablename
Order By Cols.ColumnId Desc) As RevColNo
From DBC.Tables Tbl
Join DBC.Columns Cols
On Tbl.Databasename = Cols.Databasename
And Tbl.Tablename = Cols.TableName
Where Tbl.Databasename = '$db_name'
And Tbl.Tablekind = 'T'
Order By Tbl.Tablename, ColNo
;
.Export Reset
.Run File CViews.sql

This is the working version on TD version 15.00.
I added missing "," and change to the dbc.tablesV and dbc.ColumnsV.
.os rm CViews.sql
.Export Report File = CViews.sql
.set width 300
.Rtitle ''
.Foldline on
.Format Off
.set heading '';
.set heading off;
.set UNDERLINE OFF;
.Omit On 4,5
Select
CASE When ColNo = 1
THEN 'Replace View
$view_db_name.VW_'||Tbl.Tablename||' As locking row for access
Select '
Else ', ' END (Title '')
, Cols.Columnname (Title '')
, CASE WHEN RevColNo = 1 THEN '
From $db_name.'||Tbl.Tablename||';'
Else '' END (Title '')
, Row_Number () Over(Partition By Tbl.Tablename
Order By Cols.ColumnId) As ColNo
, Row_Number () Over(Partition By Tbl.Tablename
Order By Cols.ColumnId Desc) As RevColNo
From DBC.TablesV Tbl
Join DBC.ColumnsV Cols
On Tbl.Databasename = Cols.Databasename
And Tbl.Tablename = Cols.TableName
Where Tbl.Databasename = '$db_name'
And Tbl.Tablekind = 'T'
and Tbl.Tablename not like 'WRK_%'
and Tbl.Tablename not like 'ZZ_%'
Order By Tbl.Tablename, ColNo
;
.Export Reset
.Run File CViews.sql

Related

Nested Query Sql Oracle Sort

Can anyone give me right syntax to sort this query? I want to sort base on column DocNum desc and LineNo asc
Thanks
select distinct * from (
select a.ildoc"DocNum", replace(round(a.illnid/1000,2),',','.')"LineNo",
replace(round(a.iltgn/1000,2),',','.')"TrnsctionGroup",
case when a.ilfrto = 'F' then
'From'
else
'To'
end"F/T",
a.ilitm"Item", c.imdsc1"Desc",
replace(round(a.iltrqt/10000,2),',','.')"Qty", a.illotn"LotSerial",
case when INSTR(a.illotn,': ') = 0 then
' '
else
to_char(substr(a.illotn,INSTR(a.illotn,': ')+2))
end"Serial",
d.iolot1"Memo1", d.iolot2"Memo2"
from proddta.f4111 a
inner join proddta.f4111 e on a.ildoc = e.ildoc
inner join proddta.f4101 c on c.IMITM = a.ilitm
left join proddta.f4108 d on a.illotn = d.iolotn and d.iomcu = a.ilmcu and
d.ioITM = a.ilitm
where a.ilmcu = 18001 and a.ildct = 'IE'
and e.ilitm = 56233
order by a.ildoc desc, a.iljeln asc
)--order by a.ildoc"DocNum" desc, a.iljeln asc
SELECT DISTINCT *
FROM ( SELECT a.ildoc
"DocNum",
REPLACE (ROUND (a.illnid / 1000, 2), ',', '.')
"LineNo",
REPLACE (ROUND (a.iltgn / 1000, 2), ',', '.')
"TrnsctionGroup",
CASE WHEN a.ilfrto = 'F' THEN 'From' ELSE 'To' END
"F/T",
a.ilitm
"Item",
c.imdsc1
"Desc",
REPLACE (ROUND (a.iltrqt / 10000, 2), ',', '.')
"Qty",
a.illotn
"LotSerial",
CASE
WHEN INSTR (a.illotn, ': ') = 0
THEN
' '
ELSE
TO_CHAR (
SUBSTR (a.illotn, INSTR (a.illotn, ': ') + 2))
END
"Serial",
d.iolot1
"Memo1",
d.iolot2
"Memo2"
FROM proddta.f4111 a
INNER JOIN proddta.f4111 e ON a.ildoc = e.ildoc
INNER JOIN proddta.f4101 c ON c.IMITM = a.ilitm
LEFT JOIN proddta.f4108 d
ON a.illotn = d.iolotn
AND d.iomcu = a.ilmcu
AND d.ioITM = a.ilitm
WHERE a.ilmcu = 18001 AND a.ildct = 'IE' AND e.ilitm = 56233
ORDER BY "DocNum" DESC, a.iljeln ASC)

SQL Server - using variable in triggers

I have a trigger set on a table to run after Insert and I want to query the incoming data with that already in the target table, then append a different message based on the changes identified.
Here's what I have so far
ALTER TRIGGER [dbo].[trg_Measure_Insert_Audit]
ON [dbo].[Measures_slave]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #message VARCHAR(MAX)
insert into aud_Measures
(
measure_FK,
[description],
oldname,
[newname],
milestone
)
select
i.measure_PK,
CASE
WHEN (SELECT TOP 1 measure_name FROM Measures_slave s WHERE s.slave_PK = i.slave_PK -1) <> i.measure_name THEN 'Measure Name Changed to <b> ' + i.measure_name + ' </b>'
END,
(SELECT TOP 1 measure_name FROM Measures_slave s WHERE s.slave_PK = i.slave_PK -1),
i.measure_name,
--'Test Audit Entry',
'Yes'
from
inserted i
END
I want to replace the CASE WHEN with a list of either IFs or WHENs that go down each field on both measure_slave and Inserted and append a message to #message if a difference is found.
I'm trying to achieve this, essentially:
select
i.measure_PK,
CASE
--WHEN (SELECT TOP 1 measure_name FROM Measures_slave s WHERE s.slave_PK = i.slave_PK -1) <> i.measure_name THEN 'Measure Name Changed to <b> ' + i.measure_name + ' </b>'
WHEN (SELECT TOP 1 measure_name FROM Measures_slave s WHERE s.slave_PK = i.slave_PK -1) <> i.measure_name SET #message = 'Measure Name Changed to <b> ' + i.measure_name + ' </b>'
WHEN (SELECT TOP 1 calculation_steps FROM Measures_slave s WHERE s.slave_PK = i.slave_PK -1) <> i.calculation_steps SET #message = #message + 'Steps changed to: <b> ' + i.calculation_steps + ' </b>'
END,
(SELECT TOP 1 measure_name FROM Measures_slave s WHERE s.slave_PK = i.slave_PK -1),
i.measure_name,
--'Test Audit Entry',
'Yes'
from
inserted i
I think you may be able to achive what you need without using a variable:
ALTER TRIGGER [dbo].[trg_Measure_Insert_Audit]
ON [dbo].[Measures_slave]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO aud_Measures
(
measure_FK,
[description],
oldname,
[newname],
milestone
)
SELECT
i.measure_PK,
CASE WHEN (i.measure_name <> s.measure_name) THEN 'Measure Name Changed to <b> ' + i.measure_name + ' </b>' ELSE '' END + -- The resulting value from this line concatenates with
CASE WHEN (i.calculation_steps <> s.calculation_steps ) THEN 'Steps changed to: <b> ' + i.calculation_steps + ' </b>' ELSE '' END, -- the resulting value from of this line
s.measure_name,
i.measure_name
'Yes'
FROM Inserted i LEFT JOIN Measures_slave s ON s.slave_PK = i.slave_PK -1
-- If you want to audit only the rows that in which there IS actually a difference in any of measure_name or calculation_steps columns, then use the following:
WHERE (i.measure_name <> s.measure_name) OR (i.calculation_steps <> s.calculation_steps )
END

How to test the following SQL script in Oracle 11g

Below is a script written in Oracle 11g:
MERGE INTO tblbio t
USING (SELECT e.id, tblduplicate.cpid, e.bdt,e.LN, e.FN
FROM tblduplicate, entities where
trim(e.id) = trim(tblduplicate.id)) source
ON (t.cpid = source.cpid and trim(t.bdt) = trim(source.bdt))
WHEN MATCHED
THEN
UPDATE SET t.id = source.id, t.stat = '4'
WHERE t.cmp = 'HHCC'
AND t.thn = '2013'
AND trim(lower(source.LN)) = trim(lower(t.LN))
AND trim(lower(source.FN)) = trim(lower(t.FN))
AND nvl(trim(t.bdt), ' ') <> ' '
AND t.bdt <> '00000000'
AND nvl(trim(source.bdt), ' ') <> ' '
and source.bdt <> '00000000'
AND t.stat <> '4'
Due to my data integrity problem, this script once in awhile will generate more than 1 records. In which this script will generate error.
I want to create validation prior this script is run. When my validation generate more than 1 records I stop this script from running. How can I do that?
I tried to write the following for my validation to capture record count but Oracle just did not like it.
select* from tblbio t <-----
USING (SELECT e.id, tblduplicate.cpid, e.bdt,e.LN, e.FN
FROM tblduplicate, entities where
trim(e.id) = trim(tblduplicate.id)) source
ON (t.cpid = source.cpid and trim(t.bdt) = trim(source.bdt))
WHEN MATCHED
THEN
select * from tblbio t <-----
WHERE t.cmp = 'HHCC'
AND t.thn = '2013'
AND trim(lower(source.LN)) = trim(lower(t.LN))
AND trim(lower(source.FN)) = trim(lower(t.FN))
AND nvl(trim(t.bdt), ' ') <> ' '
AND t.bdt <> '00000000'
AND nvl(trim(source.bdt), ' ') <> ' '
and source.bdt <> '00000000'
AND t.stat <> '4'
Converting original MERGE query to select from tbiblio:
MERGE INTO ... USING --> select from ... join
WHEN MATCHED THEN UPDATE SET ... WHERE --> WHERE
Final query:
select * from tblbio t
JOIN (SELECT e.id, tblduplicate.cpid, e.bdt,e.LN, e.FN
FROM tblduplicate, entities where
trim(e.id) = trim(tblduplicate.id)) source
ON (t.cpid = source.cpid and trim(t.bdt) = trim(source.bdt))
WHERE t.cmp = 'HHCC'
AND t.thn = '2013'
AND trim(lower(source.LN)) = trim(lower(t.LN))
AND trim(lower(source.FN)) = trim(lower(t.FN))
AND nvl(trim(t.bdt), ' ') <> ' '
AND t.bdt <> '00000000'
AND nvl(trim(source.bdt), ' ') <> ' '
and source.bdt <> '00000000'
AND t.stat <> '4'

Conversion failed when converting the varchar value '*' to data type int

I'm getting this issue when i'm running nested while loops in sql server 2005.
My outer loop gets one iteration, and then my inner loop gets it's full first iteration, but my statement after the inner loop never gets executed, which then seems to break everything.
I'm lost right now and I feel like I'm missing something very easy, any help is much appreciated.
while exists(select top 1 ident from #tmpAttorneyImport (nolock) where parsed = 0 and zipcode <> '')
begin
set #intCurrentIdent = 0
set #vcrCurrentAttonreyName = ''
set #vcrCurrentZip = ''
select top 1 #intCurrentIdent = ident from #tmpAttorneyImport (nolock) where parsed = 0
select #vcrCurrentAttonreyName = ltrim(rtrim(attorneyname)) from #tmpAttorneyImport (nolock) where ident = #intCurrentIdent
select #vcrCurrentZip = ltrim(rtrim(zipcode)) from #tmpAttorneyImport (nolock) where ident = #intCurrentIdent
if(len(#vcrCurrentZip) > 3)
begin
set #vcrMinZip = ''
set #vcrMaxZip = ''
select #vcrMinZip = ltrim(rtrim(left(#vcrCurrentZip, 3)))
select #vcrMaxZip = ltrim(rtrim(right(#vcrCurrentZip, 3)))
while(convert(int, #vcrMinZip) <= convert(int, #vcrMaxZip)) -- sql is telling me this line has the error
begin
insert into #tmpAttorneysFormatted(
attorneyname,
zipcode
)
select
attorneyname = #vcrCurrentAttonreyName,
zipcode = case
when len(#vcrMinZip) = 1 then '00' + ltrim(rtrim(#vcrMinZip))
when len(#vcrMinZip) = 2 then '0' + ltrim(rtrim(#vcrMinZip))
when len(#vcrMinZip) = 3 then ltrim(rtrim(#vcrMinZip))
end
select #vcrMinZip = convert(int, #vcrMinZip) + 1
end
-- this statement does not get hit
update #tmpAttorneyImport
set
parsed = 1
where
ident = #intCurrentIdent
end
else
begin
insert into #tmpAttorneysFormatted(
attorneyname,
zipcode
)
select
attorneyname = #vcrCurrentAttonreyName,
zipcode = case
when len(#vcrCurrentZip) = 1 then '00' + ltrim(rtrim(#vcrCurrentZip))
when len(#vcrCurrentZip) = 2 then '0' + ltrim(rtrim(#vcrCurrentZip))
when len(#vcrCurrentZip) = 3 then ltrim(rtrim(#vcrCurrentZip))
end
update #tmpAttorneyImport
set
parsed = 1
where
ident = #intCurrentIdent
end
end
select #vcrMinZip = ltrim(rtrim(left(#vcrCurrentZip, 3)))
select #vcrMaxZip = ltrim(rtrim(right(#vcrCurrentZip, 3)))
How sure are you that your data is clean?
I'd put in (right after this) two lines:
print #vcrMinZip
print #vcrMaxZip
and see what is actually being parsed out of the string.

Invalid column names ERROR

i have a simple query below. but I don't know why I am getting an invalid column names error for field names and error value in where clause.
select * From (
select [SubscriberDataId]
,Case When ISNUMERIC([SubscriberCode]) = 0 Then cast([SubscriberCode]as varchar(9)) Else '~' end as [SubscriberCode]
,Case When ISDATE([Dob]) = 0 Then Cast([Dob] as Varchar(9)) Else '~' end as [Dob]
,Case When ISNUMERIC([FacetsGroup]) = 0 Then cast([FacetsGroup]as varchar(9)) Else '~' end as [FacetsGroup]
from Facets.SubscriberData) [sd]
Unpivot
(ErrorValue for FieldName in ([SubscriberCode],
[Dob],[FacetsGroup])) as x
where x.ErrorValue <> '~' and
NOT EXISTS (SELECT *
FROM Elig.dbo.ErrorTable
WHERE TableName = facets.SubscriberData
AND FieldName IN( [x].[SubscriberCode],[x].[Dob],[x].[FacetsGroup])
AND ErrorValue IN( [SubscriberCode],[Dob],[FacetsGroup]))
try
select * From
(select [SubscriberDataId],
Case When ISNUMERIC([SubscriberCode]) = 0
Then cast([SubscriberCode]as varchar(9))
Else '~' end as [SubscriberCode],
Case When ISDATE([Dob]) = 0
Then Cast([Dob] as Varchar(9))
Else '~' end as [Dob],
Case When ISNUMERIC([FacetsGroup]) = 0
Then cast([FacetsGroup]as varchar(9))
Else '~' end as [FacetsGroup]
from Facets.SubscriberData) [sd]
Unpivot (ErrorValue for FieldName in ([SubscriberCode], [Dob],[FacetsGroup])) as x where x.ErrorValue <> '~'
and NOT EXISTS (SELECT * FROM Elig.dbo.ErrorTable
WHERE TableName = facets.SubscriberData
AND FieldName IN( '[x].[SubscriberCode]','[x].[Dob]','[x].[FacetsGroup]')
AND ErrorValue IN( '[SubscriberCode]','[Dob]','[FacetsGroup]'))