I have a long string.I want to check throughout this string for consecutive 15 letters if there is no space i have to manually put a space in sql server. Can any one pls help??
For eg. my string is 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ'
then it should appear like 'ABCDEFGHIJKLMNOP QRSTUVWXYZABCDE FGHIJKLMNOPQRST UVWXYZ'
#dcp1986: I tried with your function as below.
SELECT dbo.UF_StringSplitter('HeloEveryonehru Howslyfgoingonn HaveaGoodDayGoodMorning')
But an unexpected split occured. I think your function must be modified as below for the correct result:
IF EXISTS(SELECT * FROM sysobjects WHERE ID = OBJECT_ID('UF_StringSplitter'))
DROP FUNCTION UF_StringSplitter
GO
CREATE FUNCTION UF_StringSplitter (
#psCSString VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #sTemp VARCHAR(MAX)
DECLARE #tTemp VARCHAR(MAX)
SET #tTemp=''
WHILE LEN(#psCSString)>15
BEGIN
SET #sTemp = LEFT(LTRIM(#psCSString), 15)
SET #psCSString = LTRIM(SUBSTRING(#psCSString,16, LEN(#psCSString)))
IF #psCSString LIKE ' %'
SET #tTemp=#tTemp+#sTemp
ELSE
SET #tTemp=#tTemp+#sTemp+' '
END
SET #tTemp=#tTemp+#psCSString
RETURN #tTemp
END
You could use a function like this
IF EXISTS(SELECT * FROM sysobjects WHERE ID = OBJECT_ID('UF_StringSplitter'))
DROP FUNCTION UF_StringSplitter
GO
CREATE FUNCTION UF_StringSplitter
(
#psCSString VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #sTemp VARCHAR(MAX)
DECLARE #tTemp VARCHAR(MAX)
SET #tTemp=''
WHILE LEN(#psCSString)>15
BEGIN
SET #sTemp = LEFT(#psCSString, 15)
SET #psCSString = SUBSTRING(#psCSString,16, LEN(#psCSString))
IF #psCSString LIKE ' %'
SET #tTemp=#tTemp+#sTemp
ELSE
SET #tTemp=#tTemp+#sTemp+' '
END
SET #tTemp=#tTemp+#psCSString
RETURN #tTemp
END
Go
Here i have hard coded the splitting value, and you can use the function
UPDATE mytable SET mycol=dbo.UF_StringSplitter(mycol)
I don't know how to do it on a single statement, but you can create a sql function something like this
create function AddStuffCharacterInLength (#original nvarchar(100), #take int, #stuff varchar(100))
returns nvarchar(200)
AS
BEGIN
declare #result nvarchar(200)
declare #len int
declare #skip int
set #len = len(#original)
set #result = ''
set #skip = (#take * -1) + 1
while #len > 0
begin
set #result = #result + substring(#original, #skip + #take, #take)
set #len = #len - #take
set #skip = #skip + #take
if #len > 0
set #result = #result + ' '
end
RETURN #result
END
And use it like this
select dbo.AddStuffCharacterInLength ('ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ',15, ' ')
And the output should be
----------------------------------------------------------------------------------------------------
ABCDEFGHIJKLMNO PQRSTUVWXYZABCD EFGHIJKLMNOPQRS TUVWXYZ
(1 row(s) affected)
i try to set an Existence when there is a data found in my table(user). In the query, i need to use a variable. However, in the IF case, it doesn't work. Any ideal? or any alternative way to do it?
DECLARE
#myTableName varchar(1000),
#myQuery varchar(1000)
SET #myTableName = userTable //the userTable i will retrieve from a parameter
SET #myQuery = 'SELECT TOP 1 1 FROM ' + #myTableName + ''
IF EXISTS (EXEC(#myQuery))
BEGIN
print('Success')
END
ELSE
BEGIN
print('Failed')
END
SET #myQuery = 'SELECT * FROM ' + #myTableName + ' LIMIT 0,1 '
If it doesn't work, you can try this approach :
DECLARE
#myTableName varchar(1000),
#i int
SET #myTableName = userTable //the userTable i will retrieve from a parameter
SET #i = 'SELECT count(*) AS cnt FROM ' + #myTableName + ''
IF #i > 0
BEGIN
print('Success')
END
ELSE
BEGIN
print('Failed')
END
I have searched high and low, without finding an answer. So I hope that you guys n girls can help me on my way:
I cant figure out why #old_comment is NULL when I use it in "SET #new_comment...", but it returns a fine value when I use it in the outputparameter "SET #commentOldOUT..."
CREATE PROCEDURE [dbo].[SP_NY_KOMMENTAR]
#tabel NVARCHAR(100),
#id INT,
#comment NVARCHAR(1000) = NULL,
#commentOldOUT NVARCHAR(1000) = NULL OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #user NVARCHAR(30);
DECLARE #date NVARCHAR(10);
DECLARE #new_id VARCHAR(100);
DECLARE #new_comment NVARCHAR(MAX);
DECLARE #old_comment NVARCHAR(MAX);
DECLARE #old_comm NVARCHAR(MAX);
DECLARE #old NVARCHAR(MAX);
DECLARE #q2 NVARCHAR(MAX);
SET #new_id = (SELECT CAST(#id AS VARCHAR(100)));
SET #user = (SELECT ORIGINAL_LOGIN());
SET #date = (SELECT CONVERT(DATE,GETDATE()));
SET #old = 'SELECT comment FROM '+ #tabel +' WHERE id = ' + #ny_id;
EXEC sp_executesql
#query = #old,
#params = N'#old_comm NVARCHAR(MAX) OUTPUT',
#old_com = #old_comm OUTPUT;
SET #old_comment = (SELECT #old_comm);
SET #commentOldOUT = #old_comment;
SET #new_comment = COALESCE(#old_comment + CHAR(13),'') + '[' + #user + ' ' + #date + '] ' + #comment;
SET #q2 = N'UPDATE ' + #tabel + ' SET comment = ''' + #new_comment + ''' WHERE id = ' + #ny_id;
EXEC (#q2);
END
Sorry, I tried your query but for me it works fine! Have you tried to "debug" your query? You can see the value of every variable when in debug. (The green arrow in SQL Server 2008)
I'm guessing that you didn't pass a value explicitly for the #comment parameter? If so, the problem would be here:
SET #new_comment = COALESCE(#old_comment + CHAR(13),'') + '[' + #user + ' ' + #date + '] ' + #comment;
The parameter #comment has a default value of NULL and concatenating anything with NULL results in NULL. That would explain why #old_comment, #user and #date all have values, but when it put it all together then #new_comment is NULL. This would be a better default value:
#comment NVARCHAR(1000) = '',
And your code as written is a bit messy, I assume that #old_comment and #commentOldOUT are only for debugging purposes? I don't see why you don't use #old_comm directly.
Finally, if you're working with dynamic SQL then I strongly recommend adding a debugging parameter to print out your SQL strings easily. It's a very useful troubleshooting tool, especially if you don't have SSMS available.
Well I can now see that I did several things wrong, below is the new, and now working, stored procedure:
CREATE PROCEDURE [dbo].[SP_NY_KOMMENTAR]
#tabel NVARCHAR(100),
#id INT,
#comment NVARCHAR(1000) = NULL
AS
IF #comment IS NOT NULL
BEGIN
SET NOCOUNT ON;
DECLARE #user NVARCHAR(30);
DECLARE #date NVARCHAR(10);
DECLARE #SQLSelect nvarchar(500);
DECLARE #ParmSelect nvarchar(500);
DECLARE #old_comment NVARCHAR(MAX);
DECLARE #old_commentOUT NVARCHAR(MAX);
DECLARE #new_comment NVARCHAR(MAX);
DECLARE #SQLUpdate nvarchar(500);
DECLARE #ParmUpdate nvarchar(500);
SET #user = (SELECT ORIGINAL_LOGIN());
SET #date = (SELECT CONVERT(DATE,GETDATE()));
SET #SQLSelect = N'SELECT #old_commentOUT = kommentar FROM ' + QUOTENAME(#tabel) + ' WHERE id = #id';
SET #ParmSelect = N'#id INT, #old_commentOUT NVARCHAR(MAX) OUTPUT';
EXEC sp_executesql
#SQLSelect,
#ParmSelect,
#id = #id,
#old_commentOUT = #old_comment OUTPUT;
SET #old_comment = (SELECT #old_comment);
SET #new_comment = COALESCE(#old_comment + CHAR(13) + CHAR(10),'') + '[' + #user + ' ' + #date + '] ' + #comment;
SET #SQLUpdate = N'UPDATE ' + QUOTENAME(#tabel) + ' SET kommentar = #new_comment WHERE id = #id';
SET #ParmUpdate = N'#id INT, #new_comment NVARCHAR(MAX)';
EXEC sp_executesql
#SQLUpdate,
#ParmUpdate,
#id = #id,
#new_comment = #new_comment;
END
For example I weren't using parameterbinding correct, after that I tried to bind tabelnames as a parameter...
The dynamica query I have below works but wondering if what I have below can be optimized or if there is a better way of doing it.
I have a web form where the user enters a location and Date Collected. For the date collected, I have a From Date Collected and To Date Collected. The user an leave the To date collected blank in which case it will do anything greater than the From Date Collected.
Note how I am doing the IS NOT NULL and 1=1 below. Also wondering if a dynamic SQL is the best approach or if there is a simpler way of doing this.
DECLARE #sql varchar(max);
SET #sql = 'SELECT * from tblProgram WHERE 1=1'
IF (#Location IS NOT NULL)
BEGIN
SET #sql = #sql + ' AND Location = ' + #Location
END
IF (#FromDateCollected IS NOT NULL AND #ToDateCollected IS NOT NULL)
BEGIN
SET #sql = #sql + ' AND pw.DateCollected >= ' + QUOTENAME(convert(varchar, #FromDateCollected,101),'''')
+ ' AND pw.DateCollected <= ' + QUOTENAME(convert(varchar, #ToDateCollected,101),'''')
END
ELSE IF (#FromDateCollected IS NOT NULL AND #ToDateCollected IS NULL)
BEGIN
SET #sql = #sql + ' AND pw.DateCollected >= ' + QUOTENAME(convert(varchar, #FromDateCollected,101),'''')
END
exec(#sql)
Well you can do as ta.speot.is comments use static SQL and do
WHERE x is null or x > date_column?
However if you insist on using Dynamic SQL you should use a parameterized SQL statement using sp_executeSQL
Its easier to read, you don't have to use quotename, and you're protected from SQL Injection
DECLARE #Location int
DECLARE #FromDateCollected datetime
DECLARE #ToDateCollected datetime
SET #ToDateCollected = '1/02/2012'
DECLARE #sql nvarchar(max)
DECLARE #ParmDefinition nvarchar(max)
SET #ParmDefinition = N'#Location int , #FromDateCollected datetime, #ToDateCollected datetime ';
SET #sql = N'SELECT * from tblProgram WHERE 1=1'
IF (#Location IS NOT NULL)
BEGIN
SET #sql = #sql + N' AND Location = #Location'
END
IF (#FromDateCollected IS NOT NULL AND #ToDateCollected IS NOT NULL)
BEGIN
SET #sql = #sql + N' AND pw.DateCollected >= #FromDateCollected '
+ N' AND pw.DateCollected <= #ToDateCollected '
END
ELSE IF (#FromDateCollected IS NOT NULL AND #ToDateCollected IS NULL)
BEGIN
SET #sql = #sql + N' AND pw.DateCollected >= #FromDateCollected'
END
exec sp_executesql #SQL, #ParmDefinition, #Location = #Location,
#FromDateCollected = #FromDateCollected,
#ToDateCollected = #ToDateCollected
DEMO
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