Sybase : How I can get table definition using query? - sybase

I want to generate create table script in Sybase Central. I used:
SELECT * FROM INFORMATION_SCHEMA.TABLES
It gives information in table format and I don't need this kind of format and info.
And I also don't want to use ddlgen command.
I found the same script in SQL (answered by #Shnugo):
How I can get table definition in SQL SERVER 2008 R2 using SQL query?
I searched all where but cannot get any script like this. I don't want to create same as sql in sybase, as I am doing it right now.

OK thanx I got the answer :
There is a procedure which fetch the all tables' ddl in database:
use sybsystemprocs
go
if object_id('dbo.sp_ddl_create_table') is not null
drop procedure sp_ddl_create_table
print "Dropping sp_ddl_create_table"
go
create proc sp_ddl_create_table
as
-- Creates the DDL for all the user tables in the
-- current database
select right('create table ' + so1.name + '(' + '
', 255 * ( abs( sign(sc1.colid - 1) - 1 ) ) )+
sc1.name + ' ' +
st1.name + ' ' +
substring( '(' + rtrim( convert( char, sc1.length ) ) + ') ', 1,
patindex('%char', st1.name ) * 10 ) +
substring( '(' + rtrim( convert( char, sc1.prec ) ) + ', ' + rtrim(
convert( char, sc1.scale ) ) + ') ' , 1, patindex('numeric', st1.name ) * 10 ) +
substring( 'NOT NULL', ( convert( int, convert( bit,( sc1.status & 8 ) ) ) * 4 ) + 1,
8 * abs(convert(bit, (sc1.status & 0x80)) - 1 ) ) +
right('identity ', 9 * convert(bit, (sc1.status & 0x80)) ) +
right(',', 5 * ( convert(int,sc2.colid) - convert(int,sc1.colid) ) ) +
right(' )
' + 'go' + '
' + '
', 255 * abs( sign( ( convert(int,sc2.colid) - convert(int,sc1.colid) ) ) -
1 ) )
from sysobjects so1,
syscolumns sc1,
syscolumns sc2,
systypes st1
where so1.type = 'U'
and sc1.id = so1.id
and st1.usertype = sc1.usertype
and sc2.id = sc1.id
and sc2.colid = (select max(colid)
from syscolumns
where id = sc1.id)
order by so1.name, sc1.colid
go
if object_id('dbo.sp_ddl_create_table') is not null
begin
grant execute on sp_ddl_create_table to public
print "Created sp_ddl_create_table"
end
else
print "Failed to create sp_ddl_create_table"
go
go

Related

Validate decimal and integer values by looping through list of dynamic columns

I was tasked to validate the decimal and integer values of the columns from a list of tables. I have around 10-12 tables having different column names.
I created a lookup table which has the table name and the column names of decimal and integer as shown below. for example 'Pricedetails' and 'Itemdetails' tables have many columns of which only the ones mentioned in the Lookup table are required.
lkpTable
TableName
requiredcolumns
Pricedetails
sellingPrice,RetailPrice,Wholesaleprice
Itemdetails
ItemID,Itemprice
Pricedetails
Priceid
Mafdate
MafName
sellingPrice
RetailPrice
Wholesaleprice
01
2020-01-01
Americas
25.00
43.33
33.66
02
2020-01-01
Americas
43.45
22.55
11.11
03
2021-01-01
Asia
-23.00
-34.00
23.00
Itemdetails
ItemID
ItemPrice
Itemlocation
ItemManuf
01
45.11
Americas
SA
02
25.00
Americas
SA
03
35.67
Americas
SA
I have created a stored procedure with table name as input parameter, and able to pull the required column names of the tables (input parameter) from the lookup table and store that resultset into a table variable, below is the code.
declare #resultset Table
(
id INT identity(1,1),
tablename varchar(200) ,
ColumnNames varchar(max)
)
declare #tblname varchar(200),#sql varchar(max),#cols varchar(max),
INSERT INTO #resultset
select tablename,ColumnNames
from lkptable where tablename ='itemdetails'
select #cols = ColumnNames from #resultset;
select #tblname = TableName from #resultset;
----- Split the comma separated columnnames
Create table ##splitcols
(
ID int identity(1,1),
Name varchar(50)
)
Insert into ##splitcols
select value from string_split(#cols,',')
set #sql = 'select ' +#cols + ' from ' +#tblname
--print (#cols)
exec (#sql)
select * from ##splitcols
On executing the above code i get the below result sets, similarly what ever table name i provide i can get the required columns and its relevant data, now i am stuck at this point on how to validate whether the columns are decimal or int. I tried using while loop and cursor to pass the Name value from Resultset2, to the new dynamic query, somehow i don't find any way on how to validate.
ItemID
ItemPrice
01
45.11
02
25.00
03
35.67
Resultset2
ID
Name
01
ItemID
02
ItemPrice
you can validate in this way
insert into #splitcols values (1.1),(1.11)
select case when (t * 100)%10 = 0 then 1 else 0 end as valid from #splitcols
Similarly for number/integer
You can generate one giant UNION ALL query using dynamic SQL, then run it.
Each query would be of the form:
SELECT
TableName = 'SomeTable',
ColumnName,
IsInt
FROM (
SELECT
[Column1] = CASE WHEN COUNT(CASE WHEN ROUND([Column1], 0) <> [Column1] THEN 1 END) = 0 THEN 'All ints' ELSE 'Not All ints' END,
[Column2] = CASE WHEN COUNT(CASE WHEN ROUND([Column2], 0) <> [Column2] THEN 1 END) = 0 THEN 'All ints' ELSE 'Not All ints' END
FROM SomeTable
) t
UNPIVOT (
ColumnName FOR IsInt IN (
[Column1], [Column2]
)
) u
The script is as follows
DECLARE #sql nvarchar(max);
SELECT #sql = STRING_AGG('
SELECT
TableName = ' + QUOTENAME(t.name, '''') + ',
ColumnName,
IsInt
FROM (
SELECT ' + c.BeforePivotCoumns + '
FROM ' + QUOTENAME(t.name) + '
) t
UNPIVOT (
ColumnName FOR IsInt IN (
' + c.UnpivotColumns + '
)
) u
', '
UNION ALL '
)
FROM sys.tables t
JOIN lkpTable lkp ON lkp.TableName = t.name
CROSS APPLY (
SELECT
BeforePivotCoumns = STRING_AGG(CAST('
' + QUOTENAME(c.name) + ' = CASE WHEN COUNT(CASE WHEN ROUND(' + QUOTENAME(c.name) + ', 0) <> ' + QUOTENAME(c.name) + ' THEN 1 END) = 0 THEN ''All ints'' ELSE ''Not All ints'' END'
AS nvarchar(max)), ','),
UnpivotColumns = STRING_AGG(QUOTENAME(c.name), ', ')
FROM sys.columns c
JOIN STRING_SPLIT(lkp.requiredcolumns, ',') req ON req.value = c.name
WHERE c.object_id = t.object_id
) c;
PRINT #sql;
EXEC sp_executesql #sql;
db<>fiddle
If you are on an older version of SQL Server then you can't use STRING_AGG and instead you need to hack it with FOR XML and STUFF.
DECLARE #unionall nvarchar(100) = '
UNION ALL ';
DECLARE #sql nvarchar(max);
SET #sql = STUFF(
(SELECT #unionall + '
SELECT
TableName = ' + QUOTENAME(t.name, '''') + ',
ColumnName,
IsInt
FROM (
SELECT ' + STUFF(c1.BeforePivotCoumns.value('text()[1]','nvarchar(max)'), 1, 1, '') + '
FROM ' + QUOTENAME(t.name) + '
) t
UNPIVOT (
ColumnName FOR IsInt IN (
' + STUFF(c2.UnpivotColumns.value('text()[1]','nvarchar(max)'), 1, 1, '') + '
)
) u'
FROM sys.tables t
JOIN (
SELECT DISTINCT
lkp.TableName
FROM lkpTable lkp
) lkp ON lkp.TableName = t.name
CROSS APPLY (
SELECT
',
' + QUOTENAME(c.name) + ' = CASE WHEN COUNT(CASE WHEN ROUND(' + QUOTENAME(c.name) + ', 0) <> ' + QUOTENAME(c.name) + ' THEN 1 END) = 0 THEN ''All ints'' ELSE ''Not All ints'' END'
FROM lkpTable lkp2
CROSS APPLY STRING_SPLIT(lkp2.requiredcolumns, ',') req
JOIN sys.columns c ON req.value = c.name
WHERE c.object_id = t.object_id
AND lkp2.TableName = lkp.TableName
FOR XML PATH(''), TYPE
) c1(BeforePivotCoumns)
CROSS APPLY (
SELECT
', ' + QUOTENAME(c.name)
FROM lkpTable lkp2
CROSS APPLY STRING_SPLIT(lkp2.requiredcolumns, ',') req
JOIN sys.columns c ON req.value = c.name
WHERE c.object_id = t.object_id
AND lkp2.TableName = lkp.TableName
FOR XML PATH(''), TYPE
) c2(UnpivotColumns)
FOR XML PATH(''), TYPE
).value('text()[1]','nvarchar(max)'), 1, LEN(#unionall), '');
PRINT #sql;
EXEC sp_executesql #sql;
db<>fiddle

Sort COALESCE generated columns in a dynamic pivot table

I would like to sort the columns, but I get the following error:
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.
The years select query returns them in order, but they are shuffled when handled by the COALESCE function.
How can I prevent this? Or even better, control the sorting?
NOTE: The sorting works if I put a TOP 10 in the subquery. Super weird...
-- variables
DECLARE #sql AS varchar(max)
DECLARE #pivot_list AS varchar(max) -- Leave NULL for COALESCE technique
DECLARE #select_list AS varchar(max) -- Leave NULL for COALESCE technique
-- columns
SELECT -- top 10 makes the sorting work
-- [2018], [2020], [2017], [2019] -- not ordered
#pivot_list = COALESCE(#pivot_list + ', ', '') + '[' + PIVOT_COLUMN + ']',
#select_list = COALESCE(#select_list + ', ', '') + 'ISNULL([' + PIVOT_COLUMN + '], 0) as [' + PIVOT_COLUMN + ']'
FROM (
SELECT
-- 2017, 2018, 2019, 2020 -- ordered
cast(year(addate) as nvarchar(4)) as PIVOT_COLUMN
FROM tHE_Move M
where addate >= '01.01.2017'
group by year(addate)
-- order by year(addate) asc -- <-------------------------------------- doesn't work
) as PIVOT_COLUMNS
-- query
SET #sql = '
; WITH PivotData AS (
select
shop,
y AS PIVOT_COLUMN,
sum(revenueNoVAT) revenueNoVAT
from (
SELECT
SS.acName2 shop,
year(m.addate) y,
MI.anPVVATBase revenueNoVAT
FROM tHE_MoveItem MI
JOIN tHE_Move M ON MI.acKey = M.acKey
JOIN tHE_SetSubj SS ON M.acIssuer = SS.acSubject
WHERE m.acDocType in (
' + '''3210''' + ',
' + '''3220''' + ',
' + '''3230''' + ',
' + '''3240''' + '
)
) t1
group by
shop,
y
)
SELECT shop, ' + #select_list + '
FROM PivotData
PIVOT (
sum(revenueNoVAT)
FOR PIVOT_COLUMN
IN (' + #pivot_list + ')
) piv
order by shop desc
'
-- execution
EXEC (#sql)

Join execute query to table

I have 2 tables :
and
.
Then I have this code which creates dynamic pivot table from 1st table and joins it with 2nd table.
DECLARE #cols AS NVARCHAR( MAX ),
#query AS NVARCHAR( MAX )
SET #cols = STUFF( ( SELECT ', ' + QUOTENAME( Nazev )
FROM Tab1
FOR XML PATH( '' ),
TYPE
).value( '.', 'NVARCHAR( MAX )' ),
1,
1,
''
)
SET #query = 'SELECT ZamestnanecID,' + #cols +
'FROM ( SELECT ZamestnanecID,
Tab1.Nazev AS Nazev2,
tab2.[castka]
FROM Tab1
JOIN Tab2 On Tab2.typ = Tab1.Id
) AS prePivot
PIVOT
(
SUM( castka )
FOR Nazev2 IN (' + #cols + ')
) p'
execute(#query)
And i need to somehow store the executed query so i can join it with tab3 by ZamestnanecId.It contains these columns: Jméno, Příjmení, ZaměstnanecId.
(i can't post image because of image limit)
Any ideas how to do it ?
It would be best to use executed query as "from" parameter in select but it is not necessary
You cannot store results but can instead continue using dynamic query like below
DECLARE
#cols AS NVARCHAR( MAX ),
#query AS NVARCHAR( MAX )
SET #cols = STUFF( ( SELECT ', ' + QUOTENAME( Nazev )
FROM Tab1
FOR XML PATH( '' ),
TYPE
).value( '.', 'NVARCHAR( MAX )' ),
1,
1,
''
)
SET #query = 'SELECT * FROM tab3 t3 JOIN '+
'( SELECT ZamestnanecID,' + #cols +
' FROM ( SELECT ZamestnanecID,
Tab1.Nazev AS Nazev2,
tab2.[castka]
FROM Tab1
JOIN Tab2 On Tab2.typ = Tab1.Id
) AS prePivot
PIVOT
(
SUM( castka )
FOR Nazev2 IN (' + #cols + ')
) p ) t '+
' on t.ZamestnanecId=t3.ZamestnanecId'
execute(#query)

Dynamic SQL string returns NULL

I am trying to construct a dynamic SQL statement and for some reason it is not returning the expected results.
This is my query
DECLARE #user_script AS VARCHAR(MAX);
SELECT #user_script += 'IF NOT EXISTS (SELECT [name] FROM sys.database_principals WHERE [name] = '
+ SPACE(1) + '''' + [name] + '''' + ') BEGIN CREATE USER ' + SPACE(1)
+ QUOTENAME([name]) + ' FOR LOGIN ' + QUOTENAME([name])
+ ' WITH DEFAULT_SCHEMA = ' + QUOTENAME([default_schema_name])
+ SPACE(1) + 'END; '
FROM sys.database_principals AS rm
WHERE [type] IN ( 'U', 'S', 'G' )
AND rm.default_schema_name IS NOT NULL;
PRINT ( #user_script );
My problem is that the print statement is not returning anything which I think is because the #user_script variable is NULL.
To evaluate if my table is actually returning results I ran this query (exact copy of the above query without assigning it to a variable) and this query returns 10 rows
SELECT 'IF NOT EXISTS (SELECT [name] FROM sys.database_principals WHERE [name] = '
+ SPACE(1) + '''' + [name] + '''' + ') BEGIN CREATE USER ' + SPACE(1)
+ QUOTENAME([name]) + ' FOR LOGIN ' + QUOTENAME([name])
+ ' WITH DEFAULT_SCHEMA = ' + QUOTENAME([default_schema_name])
+ SPACE(1) + 'END; '
FROM sys.database_principals AS rm
WHERE [type] IN ( 'U', 'S', 'G' )
AND rm.default_schema_name IS NOT NULL;
I tried replacing the function QUOTENAME() with quotes and SPCACE() with actual space but I got the same issue.
I finally checked to see if any of the returned results from the second query is NULL. But none of the rows was a NULL.
Thanks for your help
Try putting a
SET #user_script = ''
on the line before your
select #user_script += ....
You can start the select with
SELECT #user_script = ISNULL(#user_script, '') + ...

How to work "script Table as" , "Create table" script in sql management studio

I want to get the "CREATE" script for all tables.
Is there any script, like sp_helptext?
How can I get the script called when "Script Table as" -> "Create table"
is selected?
You can right click on the database and go to Tasks -> Generate Scripts.
This will walk you through scripting out all of the scripts you want.
You may use Generate script option in SQL Server.
Tasks->Generate Scripts
There you can take script as your needs.
You could use what Stefan and gbn have suggested. Additionally if u want scripts for the exact replica for ur DB then look at Microsoft SQL Server Database Publishing Wizard. It comes built into VS 2008 +
Already somebody give the right answer to this question
The best method is Rightclick the database then Tasks->Generate Scripts
But you are point out because of some reasons you cannot use the method.
if you are looking for a method using query then you can take the below method it will return the schema of your table
Go
Create Function ShowMyTableData
(
#vsTableName varchar(50)
)
Returns
VarChar(Max)
With ENCRYPTION
Begin
Declare #ScriptCommand varchar(Max)
Select #ScriptCommand =
' Create Table [' + SO.name + '] (' + o.list + ')'
+
(
Case
When TC.Constraint_Name IS NULL
Then ''
Else 'ALTER TABLE ' + SO.Name + ' ADD CONSTRAINT ' +
TC.Constraint_Name + ' PRIMARY KEY ' + ' (' + LEFT(j.List, Len(j.List)-1) + ')'
End
)
From sysobjects As SO
Cross Apply
(
Select
' [' + column_name + '] ' +
data_type +
(
Case data_type
When 'sql_variant'
Then ''
When 'text'
Then ''
When 'decimal'
Then '(' + Cast( numeric_precision_radix As varchar ) + ', ' + Cast( numeric_scale As varchar ) + ') '
Else Coalesce( '(' +
Case
When character_maximum_length = -1
Then 'MAX'
Else Cast( character_maximum_length As VarChar )
End + ')' , ''
)
End
)
+ ' ' +
(
Case
When Exists (
Select id
From syscolumns
Where
( object_name(id) = SO.name )
And
( name = column_name )
And
( columnproperty(id,name,'IsIdentity') = 1 )
)
Then 'IDENTITY(' +
Cast( ident_seed(SO.name) As varchar ) + ',' +
Cast( ident_incr(SO.name) As varchar ) + ')'
Else ''
End
) + ' ' +
(
Case
When IS_NULLABLE = 'No'
Then 'NOT '
Else ''
End
) + 'NULL ' +
(
Case
When information_schema.columns.COLUMN_DEFAULT IS NOT NULL
Then 'DEFAULT ' + information_schema.columns.COLUMN_DEFAULT
ELse ''
End
) + ', '
From information_schema.columns
Where
( table_name = SO.name )
Order by ordinal_position
FOR XML PATH('')) o (list)
Inner Join information_schema.table_constraints As TC On (
( TC.Table_name = SO.Name )
AND
( TC.Constraint_Type = 'PRIMARY KEY' )
And
( TC.TABLE_NAME = #vsTableName )
)
Cross Apply
(
Select '[' + Column_Name + '], '
From information_schema.key_column_usage As kcu
Where
( kcu.Constraint_Name = TC.Constraint_Name )
Order By ORDINAL_POSITION
FOR XML PATH('')
) As j (list)
Where
( xtype = 'U' )
AND
( Name NOT IN ('dtproperties') )
Return #ScriptCommand
End
you can call your function like
Select [dbo].ShowMyTableData ('tablename')
Extension :
if you need data too then you can use the following query
select 'insert into tablename values('+yourcolumnanme+','+columnanme2.....+')' from tablename

Resources