The company decided to change their domain name and no longer will accept the old email addresses. need toupdate the email address inside all of those subscriptions without going into each subscription and updating them.
USE abc
DECLARE #list TABLE
(
id INTEGER IDENTITY(1, 1) PRIMARY KEY,
oldemailaddress VARCHAR(100),
newemailaddress VARCHAR(100)
)
INSERT INTO #list
(oldemailaddress,
newemailaddress)
SELECT [global address],
[abc-address]
FROM [dbo].[abc-data final]
--select * from #list
DECLARE #OldEmailAddress VARCHAR(100),
#NewEmailAddress VARCHAR(100),
#totalRecords INT,
#I INT,
#SubscriptionID UNIQUEIDENTIFIER
DECLARE email_cursor CURSOR FOR
SELECT oldemailaddress,
newemailaddress
FROM #list
OPEN email_cursor
FETCH next FROM email_cursor INTO #OldEmailAddress, #NewEmailAddress
WHILE ##FETCH_STATUS = 0
BEGIN
BEGIN TRANSACTION
UPDATE abc.dbo.subscription_email_test
SET extensionsettings = CONVERT(NTEXT, Replace(
CONVERT(VARCHAR(max), extensionsettings)
,
#OldEmailAddress,
#NewEmailAddress))
FROM abc.dbo.subscription_email_test
WHERE CONVERT(VARCHAR(max), extensionsettings) LIKE
'%'
+ CONVERT(VARCHAR(100
),
#OldEmailAddress
)
+ '%'
--rollback transaction
COMMIT TRANSACTION
PRINT 'Old: ' + #OldEmailAddress + ' New: '
+ #NewEmailAddress + 'SubscriptionID: '
+ Isnull(CONVERT(NVARCHAR(max), #SubscriptionID), 'NOT FOUND')
FETCH next FROM email_cursor INTO #OldEmailAddress, #NewEmailAddress
END
CLOSE email_cursor
USE abc
DECLARE #list TABLE
(
id INTEGER IDENTITY(1, 1) PRIMARY KEY,
oldemailaddress VARCHAR(100),
newemailaddress VARCHAR(100)
)
INSERT INTO #list
(oldemailaddress,
newemailaddress)
SELECT [global address],
[abc-address]
FROM [dbo].[abc-data final]
--select * from #list
DECLARE #OldEmailAddress VARCHAR(100),
#NewEmailAddress VARCHAR(100),
#totalRecords INT,
#I INT,
#SubscriptionID UNIQUEIDENTIFIER
DECLARE email_cursor CURSOR FOR
SELECT oldemailaddress,
newemailaddress
FROM #list
OPEN email_cursor
FETCH next FROM email_cursor INTO #OldEmailAddress, #NewEmailAddress
WHILE ##FETCH_STATUS = 0
BEGIN
BEGIN TRANSACTION
UPDATE abc.dbo.subscription_email_test
SET extensionsettings = CONVERT(NTEXT, Replace(
CONVERT(VARCHAR(max), extensionsettings)
,
#OldEmailAddress,
#NewEmailAddress))
FROM abc.dbo.subscription_email_test
WHERE CONVERT(VARCHAR(max), extensionsettings) LIKE
'%'
+ CONVERT(VARCHAR(100
),
#OldEmailAddress
)
+ '%'
COMMIT TRANSACTION
PRINT 'Old: ' + #OldEmailAddress + ' New: '
+ #NewEmailAddress + 'SubscriptionID: '
+ Isnull(CONVERT(NVARCHAR(max), #SubscriptionID), 'NOT FOUND')
FETCH next FROM email_cursor INTO #OldEmailAddress, #NewEmailAddress
END
CLOSE email_cursor
DEALLOCATE email_cursor ;
----------
Related
I have a list of employee names, and a list of tables. I need to iterate all employee names and find which table(s) the employee name exists in. All of the tables to iterate exist on the same server and the same database.
Sample data structure
Create Table TableNamesToCheck (dbName varchar(15))
Insert Into TableNamesToCheck
Values ('table1'), ('table2'), ('table3'), ('table4'), ('table5'),
('table6'), ('table7'), ('table8'), ('table9'), ('table10')
Create Table EN (employeename varchar(100))
Insert Into EN
Values ('Richard Marx'), ('Joseph Jones'), ('Mark Badcock'),
('Frank Fins'), ('Richard James'), ('Fall Fren'), ('Hiu Hen')
Thank you #Giorgi --- I understand using Cursor for my tablenames, but how do I join the two tables, when their is no similar field to join the 2 tables on? This is what I have (work in progress) if I understand what you are explaining this is my syntax, but it gives me the below error for each employee and each table...
Msg 207, Level 16, State 1, Line 1
Invalid column name 'employeename'.
Msg 207, Level 16, State 1, Line 1
Invalid column name 'Richard'.
Declare #dbname varchar(25), #empname varchar(100), #sql varchar(Max)
Create Table TableNamesToCheck (dbName varchar(15))
Insert Into TableNamesToCheck
Values ('table1'), ('table2'), ('table3'), ('table4'), ('table5'),
('table6'), ('table7'), ('table8'), ('table9'), ('table10')
Create Table EN (employeename varchar(100))
Insert Into EN
Values ('Richard Marx'), ('Joseph Jones'), ('Mark Badcock'),
('Frank Fins'), ('Richard James'), ('Fall Fren'), ('Hiu Hen')
Declare c1 Cursor For
Select dbname
From TableNamesToCheck
Open c1
Fetch Next from c1 into #dbname
Declare c2 Cursor For
Select employeename
From EN
Open c2
Fetch Next from c2 into #empname
While ##FETCH_STATUS = 0
Begin
While ##FETCH_STATUS = 0
Begin
Set #sql = 'Select '+#dbname+' From TableNamesToCheck where employeename IN (Select '+#empname+' from EN)'
Exec (#sql)
Fetch Next From c1 Into #dbname
Fetch Next From c2 Into #empname
End
End
Close c1
Close c2
Deallocate c1
Deallocate c2
Drop Table TableNamesToCheck
Drop Table EN
Not 100% sure, but you might be looking for this :-
Set Nocount On;
Declare #Sql Varchar(Max)
,#Total Int
,#RowId Int
,#EmpName Varchar(100)
,#Total2 Int
,#RowId2 Int
,#TableName Varchar(15)
Select #Sql = ''
,#EmpName = ''
,#TableName = ''
If Object_Id('tempdb.dbo.#TableNamesToCheck') Is Not Null
Begin
Drop Table #TableNamesToCheck;
End
If Object_Id('tempdb.dbo.#EN') Is Not Null
Begin
Drop Table #EN;
End
If Object_Id('tempdb.dbo.#EnTables') Is Not Null
Begin
Drop Table #EnTables;
End
Create Table #TableNamesToCheck
(
dbId Int Identity(1,1) Primary Key
,dbName Varchar(15)
)
Create Table #EN
(
RowId Int Identity(1,1) Primary Key
,employeename Varchar(100)
)
Create Table #EnTables
(
Id Int Identity(1,1) Primary Key
,EmployeeName Varchar(100)
,dbName Varchar(15)
)
Insert Into #TableNamesToCheck
Values ('table1'), ('table2'), ('table3'), ('table4'), ('table5'),
('table6'), ('table7'), ('table8'), ('table9'), ('table10')
Insert Into #EN
Values ('Richard Marx'), ('Joseph Jones'), ('Mark Badcock'),
('Frank Fins'), ('Richard James'), ('Fall Fren'), ('Hiu Hen')
Select #Total = Count(1)
,#RowId = 1
From #EN As en With (Nolock)
Select #Total2 = Count(1)
,#RowId2 = 1
From #TableNamesToCheck As et With (Nolock)
While (#RowId <= #Total)
Begin
Select #EmpName = en.employeename
From #EN As en With (Nolock)
Where en.RowId = #RowId
While (#RowId2 <= #Total2)
Begin
Select #TableName = et.dbName
From #TableNamesToCheck As et With (Nolock)
Where et.dbId = #RowId2
Select #Sql = ' If Exists ' +
' ( ' +
' Select 1 ' +
' From ' + #TableName + ' As t With (Nolock) ' +
' Where t.employeename = ''' + #EmpName + ''' ' +
' ) ' +
' Begin ' +
' Insert Into #EnTables(EmployeeName,dbName) ' +
' Select ''' + #EmpName + ''' ' +
' ,''' + #TableName + ''' ' +
' End '
----Print(#Sql)
Exec (#Sql)
Select #RowId2 = #RowId2 + 1
End
Select #RowId = #RowId + 1
,#RowId2 = 1
,#EmpName = ''
,#TableName = ''
End
Select *
From #EnTables As et With (Nolock)
How to set up a SQL Server 2008 Trigger that sends an Email Alert when a Job is Created/Deleted
I have created a trigger, with the help of many hours of research. The trigger currently emails out to a recipient when a SQL job has been enabled/disabled. The trigger has been tested and works without fail.
I would like to extend the trigger out to capture the creation and deletion of jobs as well, but I am not sure how.
Here is the code that I have:
USE [msdb]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[jobChecker]
ON sysjobs
FOR UPDATE AS
SET NOCOUNT ON
-- # DECLARE VARIABLES # --
DECLARE #username VARCHAR(50),
#hostName VARCHAR(50),
#jobName VARCHAR(100),
#newEnabled INT,
#oldEnabled INT,
#jobCreated INT,
#bodyText VARCHAR(200),
#subjectText VARCHAR(200),
#servername VARCHAR(50),
#profileName VARCHAR(50) = 'profile_name',
#recipients VARCHAR(500) = 'example#domain.com'
-- # SET VARIABLES # --
SELECT #username = SYSTEM_USER
SELECT #hostName = HOST_NAME()
SELECT #servername = ##servername
SELECT #newEnabled = ENABLED FROM Inserted
SELECT #oldEnabled = ENABLED FROM Deleted
SELECT #jobName = Name FROM Inserted
-- # CHECK FOR ENABLED/DISABLED # --
IF #newEnabled <> #oldEnabled
BEGIN
IF #newEnabled = 1
BEGIN
SET #bodyText = 'The user (' + #username + ') enabled the job from ' + #hostName + ' on ' + CONVERT(VARCHAR(20),GETDATE(),100) + '.'
SET #subjectText = #servername + ' : [' + #jobName + '] has been ENABLED'
END
IF #newEnabled = 0
BEGIN
SET #bodyText = 'The user (' + #username + ') disabled the job from ' + #hostName + ' on ' + CONVERT(VARCHAR(20),GETDATE(),100) + '.'
SET #subjectText = #servername+' : [' + #jobName + '] has been DISABLED'
END
SET #subjectText = 'SQL Job on ' + #subjectText
-- # SEND EMAIL # --
EXEC msdb.dbo.sp_send_dbmail
#profile_name = #profileName,
#recipients = #recipients,
#body = #bodyText,
#subject = #subjectText
END
try change the "FOR UPDATE" to "AFTER UPDATE, INSERT, DELETE"
this should run the trigger then for inserts and deleted from the table
you can then check if its an update , insert or delete by running something like
DECLARE #Type as varchar(1);
SET #Type = (
CASE
WHEN EXISTS(SELECT * FROM INSERTED) AND EXISTS(SELECT * FROM DELETED) THEN 'U' -- then the record was updated.
WHEN EXISTS(SELECT * FROM INSERTED) THEN 'I' --the record was inserted.
WHEN EXISTS(SELECT * FROM DELETED) THEN 'D' --the record was delete.
ELSE NULL
END)
I couldn't find an answer to this....
I have three variables and need to switch between them in While Loop
Example:
DECLARE
#tableHTML NVARCHAR(MAX),
#email nvarchar(100),
#text1 nvarchar(100),
#text2 nvarchar(100),
#text3 nvarchar(100),
#number_suffix nvarchar(1)
SET #text1 = 'State of orders for Morfeus'
SET #text2 = 'State of orders for Fenix'
SET #text3 = 'State of orders for Perseus'
SET #number_suffix = 1
WHILE (#number_suffix < 4)
BEGIN
print #text(#number_suffix) /*and here is the problem */
SET #number_suffix = (#number_suffix + 1)
END
How do I append the number to variable #text please?
I am using MS SQL 2008
Do you want to append number to variable name? This is not possible. Why you need that, perhaps solution is more straightforward....
Try out following, perhaps id does what are you looking for:
DECLARE #cities TABLE(id int IDENTITY(1,1), cityName varchar(100))
INSERT INTO #cities(cityName) VALUES ('Morfeus'), ('Fenix'), ('Morfeus')
SELECT 'State of orders for ' + cityName
FROM #cities
Output:
State of orders for Morfeus
State of orders for Fenix
State of orders for Morfeus
To print number as well:
SELECT '#' + CAST(id AS varchar(2)) + ' State of orders for ' + cityName
FROM #cities
Output:
1 State of orders for Morfeus
2 State of orders for Fenix
3 State of orders for Morfeus
The question is not quite clear what your end game is but if I understand you correctly then something like this should work (note, you need to create the parse function first):
CREATE FUNCTION [dbo].[fnParseString]
(
#Section SMALLINT,
#Delimiter CHAR,
#Text VARCHAR(MAX)
)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE #startindex NUMERIC(18,0),
#length NUMERIC(18,0),
#FieldPosition INT
SET #FieldPosition = ABS(#Section) - 1
SET #startindex = 0
WHILE #FieldPosition != 0
BEGIN
SET #FieldPosition = #FieldPosition - 1
SET #startindex = CHARINDEX(#Delimiter, #Text, #startindex + 1)
END
SET #Text = SUBSTRING(#Text, #startindex + 1, LEN(#Text) - #startindex)
SET #Text = SUBSTRING(#Text, 0, CHARINDEX(#Delimiter, #Text))
RETURN #Text
END
GO
DECLARE
#tableHTML NVARCHAR(MAX),
#email nvarchar(100),
#text nvarchar(100),
#number_suffix nvarchar(1)
SET #text = 'State of orders for Morfeus|State of orders for Fenix|State of orders for Perseus|'
SET #number_suffix = 1
WHILE (#number_suffix < 4)
BEGIN
PRINT dbo.fnParseString(#number_suffix, '|', #text)
SET #number_suffix = (#number_suffix + 1)
END
You can do it with Dynamic SQL but you'd need to reinitialize all you variables. The following will do it, but its a colossally bad idea, and you should use sll's answer instead
DECLARE
#tableHTML NVARCHAR(MAX),
#email nvarchar(100),
#number_suffix nvarchar(1),
#SQL nvarchar(max)
SET #number_suffix = 1
WHILE (#number_suffix < 4)
BEGIN
SET #SQL = N'
DECLARE #text1 nvarchar(100),
#text2 nvarchar(100),
#text3 nvarchar(100)
SET #text1 = ' + '''' + 'State of orders for Morfeus' + '''' +
'SET #text2 = ' + '''' + 'State of orders for Fenix' + '''' +
'SET #text3 = ' + '''' + 'State of orders for Perseus' + ''''
+
'PRINT #text' + #number_suffix
EXEC sp_executeSQL #SQL
SET #number_suffix = (#number_suffix + 1)
END
I want to get all the transactions applied on a specific table in SQL Server 2008.
I found the last time a table was updated using this script:
SELECT OBJECT_NAME(OBJECT_ID) AS DatabaseName, last_user_update,*
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID( 'DBName')
AND OBJECT_ID=OBJECT_ID('tableName')
I want to know all the transactions (Inserts, Updates, Deletes) for that table, and their datetime, and the query applied.
What is the best way to do this?
The only way to do this in a reasonable amount of time is to use a third party tool(as Martin said in first comment) such as ApexSQL Log that can read transaction log and get the information you need.
Note that in order for this to work your database has to be in a full recovery mode because that’s when SQL Server logs full transaction details that can be reconstructed later.
Another option is to investigate how to use undocumented fn_dblog function but this will take you a lot more time and you won’t be able to read detached logs or transaction log backups.
creating a trigger which will create a new table Emp_audit and add new tuples to it whenever any change is made to table employee
create trigger my_trigger on Employees
AFTER INSERT, UPDATE, DELETE
AS
DECLARE #What varchar(30);
DECLARE #Who varchar(30);
DECLARE #for int;
DECLARE #At time;
DECLARE #COUNTI int;
DECLARE #COUNTD int;
select #COUNTI = COUNT(*) from inserted;
select #COUNTD = COUNT(*) from deleted;
set #Who = SYSTEM_USER;
set #At = CURRENT_TIMESTAMP;
if( #COUNTD = 0 and #COUNTI = 1)
begin
set #What = 'insert';
select #for = EmployeeID from inserted i;
end
else
begin
if( #COUNTD = 1 and #COUNTI = 0)
begin
set #What = 'delete';
select #for = EmployeeID from deleted i;
end
else
begin
set #What = 'update';
select #for = EmployeeID from inserted i;
end
end
INSERT INTO EMP_Audit Values (#What, #Who, #for, #At);
You would be much better off setting up auditing for this need rather than trying to extract this information retrospectively from the transaction log.
If you are on Enterprise Edition you could use the built in SQL Server Audit functionality, otherwise it should be relative straight forward to log the desired information via triggers.
You could create your own transaction logs
Step 1: Create your own table for transaction logs
CREATE TABLE [dbo].[TransactionLogs](
[TransactionLogID] [bigint] IDENTITY(1,1) NOT NULL,
[Query] [nvarchar](max) NOT NULL,
[DateCreated] [datetime] NOT NULL,
CONSTRAINT [PK_TransactionLogs] PRIMARY KEY CLUSTERED
(
[TransactionLogID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
Step 2: Create stored procedure that create logs. (Note: Replace YourTablePKColumn with your table primary key column.)
create procedure [dbo].[sp_CreateQueryLogs]
(
#Query nvarchar(max) = null output,
#TableName nvarchar(100),
#YourTablePKColumn nvarchar(30),
#QueryTypeID tinyint --0 insert, 1 update, 2 delete
)
as
begin
declare #object_id bigint, #column_name nvarchar(100), #collation_name nvarchar(50), #column_name_id nvarchar(100) = null, #column_names nvarchar(max) = '', #column_values nvarchar(max) = '', #column_names_create nvarchar(max) = '', #values nvarchar(max) = '', #user_type_id int, #max_length nvarchar(10), #type_name nvarchar(50), #CreateTempTable nvarchar(max) = '', #is_nullable bit, #value nvarchar(max) = ''
create table #tmpValues(ColumnValues nvarchar(max))
insert into #tmpValues(ColumnValues)
exec('select CAST ( ( select * from ' + #TableName + ' where YourTablePKColumn = ' + #YourTablePKColumn + '
FOR XML PATH(''tr''), TYPE
) AS NVARCHAR(MAX) )')
select #values = ColumnValues from #tmpValues
if #QueryTypeID = 0 --insert
set #Query = 'insert into ' + #TableName + '('
else if #QueryTypeID = 1 --update
set #Query = 'update ' + #TableName + ' set '
else if #QueryTypeID = 2 --dalete
set #Query = 'delete ' + #TableName + ' '
select #object_id = object_id from sys.tables where name = #TableName
if not cursor_status('local','columnCursor') <= -1
begin
close columnCursor;
deallocate columnCursor;
end
declare columnCursor cursor local for
select name, user_type_id, convert(nvarchar(10), max_length), is_nullable from sys.columns where object_id = #object_id order by column_id ;
open columnCursor;
fetch next from columnCursor
into #column_name, #user_type_id, #max_length, #is_nullable;
while ##FETCH_STATUS = 0
begin
select #type_name = name, #collation_name = collation_name from sys.types where user_type_id = #user_type_id
if #column_name_id is null
set #column_name_id = #column_name
else
begin
set #column_names += #column_name + ', '
declare #value_keys_start nvarchar(max) = '<' + #column_name + '>', #value_keys_end nvarchar(max) = '</' + #column_name + '>'
if charindex(#value_keys_start,#values,1) = 0
begin
if #QueryTypeID = 0 --insert
set #column_values += 'null,'
else if #QueryTypeID = 1 --update
set #column_values += #column_name + ' = null,'
end
else
begin
if #QueryTypeID = 0 --insert
if #collation_name is null and not (#type_name like '%date%' or #type_name like '%time%')
set #column_values += substring(#values, charindex(#value_keys_start,#values,1) + len(#value_keys_start), charindex(#value_keys_end,#values,1) - (charindex(#value_keys_start,#values,1) + len(#value_keys_start))) + ','
else if #type_name like '%date%' or #type_name like '%time%'
set #column_values += '''' + replace(substring(#values, charindex(#value_keys_start,#values,1) + len(#value_keys_start), charindex(#value_keys_end,#values,1) - (charindex(#value_keys_start,#values,1) + len(#value_keys_start))),'T',' ') + ''','
else
set #column_values += '''' + replace(substring(#values, charindex(#value_keys_start,#values,1) + len(#value_keys_start), charindex(#value_keys_end,#values,1) - (charindex(#value_keys_start,#values,1) + len(#value_keys_start))),'''','''''') + ''','
else if #QueryTypeID = 1 --update
if #collation_name is null and not (#type_name like '%date%' or #type_name like '%time%')
set #column_values += #column_name + '=' + substring(#values, charindex(#value_keys_start,#values,1) + len(#value_keys_start), charindex(#value_keys_end,#values,1) - (charindex(#value_keys_start,#values,1) + len(#value_keys_start))) + ','
else if #type_name like '%date%' or #type_name like '%time%'
set #column_values += #column_name + '=' + '''' + replace(substring(#values, charindex(#value_keys_start,#values,1) + len(#value_keys_start), charindex(#value_keys_end,#values,1) - (charindex(#value_keys_start,#values,1) + len(#value_keys_start))),'T',' ') + ''','
else
set #column_values += #column_name + '=' + '''' + replace(substring(#values, charindex(#value_keys_start,#values,1) + len(#value_keys_start), charindex(#value_keys_end,#values,1) - (charindex(#value_keys_start,#values,1) + len(#value_keys_start))),'''','''''') + ''','
end
end
fetch next from columnCursor
into #column_name, #user_type_id, #max_length, #is_nullable;
end
if not cursor_status('local','columnCursor') <= -1
begin
close columnCursor;
deallocate columnCursor;
end
if #QueryTypeID = 0 --insert
set #Query += substring(#column_names,1,len(#column_names) - 1) + ')
values (' + substring(#column_values,1,len(#column_values) - 1) + ')'
else if #QueryTypeID = 1 --update or delete
set #Query += substring(#column_values,1,len(#column_values) - 1) + ' where YourTablePKColumn = ' + #YourTablePKColumn
else
set #Query += ' where YourTablePKColumn = ' + #YourTablePKColumn
end
Step 3: Created trigger to table you want to have transaction logs
CREATE TRIGGER trg_MyTrigger ON YouTableName
AFTER INSERT, DELETE, UPDATE
AS
BEGIN
SET NOCOUNT ON;
declare #TableName nvarchar(100) = 'YouTableName', #Query nvarchar(max), #QueryTypeID tinyint, #YourTablePKColumn nvarchar(30)
if exists(select * from deleted) and exists(select * from inserted)
begin
set #QueryTypeID = 1
if not cursor_status('local','updatedCursor') <= -1
begin
close updatedCursor;
deallocate updatedCursor;
end
declare updatedCursor cursor local for
select cast(YourTablePKColumn as nvarchar(30)) from inserted;
open updatedCursor;
fetch next from updatedCursor
into #YourTablePKColumn;
while ##FETCH_STATUS = 0
begin
exec dbo.sp_CreateQueryLogs #Query = #Query output, #TableName = #TableName, #YourTablePKColumn = #YourTablePKColumn, #QueryTypeID = #QueryTypeID
insert into TransactionLogs
(Query, DateCreated)
values (#Query,getdate())
fetch next from updatedCursor
into #YourTablePKColumn;
end
if not cursor_status('local','updatedCursor') <= -1
begin
close updatedCursor;
deallocate updatedCursor;
end
end
else if exists(select * from deleted) and not exists(select * from inserted)
begin
set #QueryTypeID = 2
if not cursor_status('local','deletedCursor') <= -1
begin
close deletedCursor;
deallocate deletedCursor;
end
declare deletedCursor cursor local for
select cast(YourTablePKColumn as nvarchar(30)) from deleted;
open deletedCursor;
fetch next from deletedCursor
into #YourTablePKColumn;
while ##FETCH_STATUS = 0
begin
exec dbo.sp_CreateQueryLogs #Query = #Query output, #TableName = #TableName, #YourTablePKColumn = #YourTablePKColumn, #QueryTypeID = #QueryTypeID
insert into TransactionLogs
(Query, DateCreated)
values (#Query,getdate())
fetch next from deletedCursor
into #YourTablePKColumn;
end
if not cursor_status('local','deletedCursor') <= -1
begin
close deletedCursor;
deallocate deletedCursor;
end
end
else
begin
set #QueryTypeID = 0
if not cursor_status('local','insertedCursor') <= -1
begin
close insertedCursor;
deallocate insertedCursor;
end
declare insertedCursor cursor local for
select cast(YourTablePKColumn as nvarchar(30)) from inserted;
open insertedCursor;
fetch next from insertedCursor
into #YourTablePKColumn;
while ##FETCH_STATUS = 0
begin
exec dbo.sp_CreateQueryLogs #Query = #Query output, #TableName = #TableName, #YourTablePKColumn = #YourTablePKColumn, #QueryTypeID = #QueryTypeID
insert into TransactionLogs
(Query, DateCreated)
values (#Query,getdate())
fetch next from insertedCursor
into #YourTablePKColumn;
end
if not cursor_status('local','insertedCursor') <= -1
begin
close insertedCursor;
deallocate insertedCursor;
end
end
END
GO
Is there a way to create table type in SQL Server 2008 based on scheme of existing table?
CREATE TABLE A (id INT, name VARCHAR(30))
CREATE TYPE type_a AS TABLE.A
Something like that.
No, this kind of composable DML is not yet possible. Microsoft has rejected this suggestion in the past, but with enough votes (e.g. more than 1!) it may get reconsidered in the future:
http://connect.microsoft.com/SQLServer/feedback/details/294130/table-valued-parameters-add-support-for-create-type-type-from-table-table-name-options-syntax-construct
You can use following stored procedure to create a type with same schema existing table may have.
Create PROCEDURE [dbo].[Sp_DefineTypeOutOfTableSchema]
#TableNames NVARCHAR(500)
AS
BEGIN
DECLARE #TableName NVARCHAR(100)
DECLARE #strSQL NVARCHAR(max)
DECLARE #strSQLCol NVARCHAR(1000)
DECLARE #ColName NVARCHAR(100)
DECLARE #ColDataTaype NVARCHAR(50)
DECLARE #ColDefault NVARCHAR(50)
DECLARE #ColIsNulable NVARCHAR(50)
DECLARE #ColCharMaxlen NVARCHAR(50)
DECLARE #ColNumPrec NVARCHAR(50)
DECLARE #ColNumScal NVARCHAR(50)
IF LEN(#TableNames) > 0 SET #TableNames = #TableNames + ','
WHILE LEN(#TableNames) > 0
BEGIN
SELECT #TableName = LTRIM(SUBSTRING(#TableNames, 1, CHARINDEX(',', #TableNames) - 1))
DECLARE schemaCur CURSOR FOR
SELECT COLUMN_NAME,DATA_TYPE,IS_NULLABLE,COLUMN_DEFAULT,CHARACTER_MAXIMUM_LENGTH,NUMERIC_PRECISION,NUMERIC_SCALE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME =#TableName
OPEN schemaCur
SELECT #strSQL=''
FETCH NEXT FROM schemaCur
INTO #ColName,#ColDataTaype,#ColIsNulable,#ColDefault,#ColCharMaxlen,#ColNumPrec,#ColNumScal
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #strSQLCol=''
SELECT #strSQLCol= '['+#ColName+'] '+'[' + #ColDataTaype +'] '
IF #ColDataTaype='nvarchar' or #ColDataTaype='char' or #ColDataTaype='varchar' or #ColDataTaype='vchar'
BEGIN
SELECT #strSQLCol=#strSQLCol+ '(' + #ColCharMaxlen +') '
END
ELSE IF #ColDataTaype='numeric' or #ColDataTaype='decimal'
BEGIN
SELECT #strSQLCol=#strSQLCol +'(' + #ColNumPrec +',' +#ColNumScal + ') '
END
IF #ColIsNulable='YES'
BEGIN
SELECT #strSQLCol=#strSQLCol+ 'NULL '
END
ELSE
BEGIN
SELECT #strSQLCol=#strSQLCol+ ' NOT NULL '
END
IF #ColDefault IS NOT NULL
BEGIN
SELECT #strSQLCol=#strSQLCol+ ' DEFAULT(' +#ColDefault + '),'
END
ELSE
BEGIN
SELECT #strSQLCol=#strSQLCol+ ' ,'
END
SELECT #strSQL=#strSQL+#strSQLCol
--print #strSQL
FETCH NEXT FROM schemaCur
INTO #ColName,#ColDataTaype,#ColIsNulable,#ColDefault,#ColCharMaxlen,#ColNumPrec,#ColNumScal
END
CLOSE schemaCur
DEALLOCATE schemaCur
--print #strSQL
SELECT #strSQL=left( #strSQL, len(#strSQL)-1)
--print #strSQL
IF EXISTS (SELECT * FROM sys.types WHERE IS_TABLE_TYPE = 1 AND name = 't_' +#TableName)
BEGIN
EXEC('DROP TYPE t_' +#TableName )
END
SELECT #strSQL = 'CREATE TYPE t_' + #TableName + ' AS TABLE (' + #strSQL + ')'
--print #strSQL
EXEC (#strSQL)
SELECT #TableNames = SUBSTRING(#TableNames, CHARINDEX(',', #TableNames) + 1, LEN(#TableNames))
END
END
you can use it like this
Exec Sp_DefineTypeOutOfTableSchema 'Table1name,Table2name'
You could experiment with creating a function that pulled the table definition out of sysobjects, systypes, syscolumns, syscomments, etc., and built a CREATE statement out of it. You'd just have to make sure to grab all of the important pieces (columns, constraints, comments, etc.) from the various sys tables.
Then call it like... EXEC myCREATEtable #template_table_name or some such...