Feeds:
Posts
Comments

Posts Tagged ‘raresql’

I really appreciate active participation of my blog readers. Yesterday, I received an inquiry from ‘Abhilash’ one of my blog readers, how to search a string value in all columns in the table and in all tables in a database.

Given below is the solution that will search a string value in all columns in the table and in all tables in a database.

Lets proceed it step by step.
Step 1:
Create given below table in tempdb database to consolidate all search result.

Use tempdb
GO
Create Table Result
(
[Sno] int identity(1,1),
[Database Name] sysname,
[Schema Name] sysname,
[Table Name] sysname,
[Column Name] sysname,
[Record Name] varchar(Max)
)

Step 2:
Create the given below stored procedure to search the string in all columns in the table and in all tables in a database.

--Create the store procedure to search a string across the tables.
Use AdventureWorks2012
GO
Create PROCEDURE Find_Record_Across_Tables_Proc
@Database sysname,
@Schema sysname,
@Table sysname,
@String VARCHAR(Max)

AS

DECLARE @SqlString varchar(Max)
DECLARE @Table_Schema sysname
DECLARE @Table_Name sysname
DECLARE @Column_Name sysname

--Declare Cursor
SET @SqlString = 'DECLARE String_cursor CURSOR FOR
Select TABLE_SCHEMA, TABLE_NAME ,COLUMN_NAME from
' + @Database +'.INFORMATION_SCHEMA.COLUMNS
Where DATA_TYPE IN (''text'',''ntext'',''varchar''
,''nvarchar'',''char'',''nchar'')'

--Filter schema name
IF @schema IS NOT NULL
Begin
SET @SqlString = @SqlString + ' And TABLE_SCHEMA=''' + @Schema + ''''
End
--Filter table name
IF @table IS NOT NULL
Begin
SET @SqlString = @SqlString + ' And TABLE_NAME=''' + @table + ''''
End

Print @SqlString
EXEC (@SqlString)

OPEN String_cursor

FETCH NEXT FROM String_cursor
INTO @Table_Schema, @Table_Name, @Column_Name

WHILE @@FETCH_STATUS = 0
BEGIN
SET @SqlString = 'IF EXISTS(SELECT ' + QUOTENAME(@Column_Name)
+ ' FROM ' + @Database + '.' + QUOTENAME(@Table_Schema)
+ '.' + QUOTENAME(@Table_Name)
+ ' WHERE ' + QUOTENAME(@Column_Name)
+ ' Like ''%' + @string + '%'')
Insert into tempdb.dbo.result
([Database Name],[Schema Name]
,[Table Name],[Column Name],[Record Name])
SELECT ''' + QUOTENAME(@Database) + ''','''
+ QUOTENAME(@Table_Schema) + ''','''
+ QUOTENAME(@Table_Name) + ''',''''
+ ''' + QUOTENAME(@Column_Name)
+ ''',' + QUOTENAME(@Column_Name)
+ ' FROM ' + @Database + '.'
+ QUOTENAME(@Table_Schema)
+ '.' + QUOTENAME(@Table_Name)
+ ' WHERE ' + QUOTENAME(@Column_Name)
+ ' Like ''%' + @string + '%'''
Print @SqlString
EXEC (@SqlString)

FETCH NEXT FROM String_cursor
INTO @Table_Schema, @Table_Name, @Column_Name

END
CLOSE String_cursor
DEALLOCATE String_cursor
GO

Step 3:
In the step 3, you can execute the above stored procedure with different parameters.
Given below are few examples of above stored procedure.

Example 1:
To search a string in all columns of all tables in a single database.

Use AdventureWorks2012
GO
Delete from tempdb.dbo.result
GO
EXEC Find_Record_Across_Tables_Proc
'AdventureWorks2012', NULL, NULL ,'Senior'
GO
Select * from tempdb.dbo.result
GO

search_string_in_all_tables1.0

Example 2:
To search a string in all columns of a single tables and in a single database.

Use AdventureWorks2012
GO
Delete from tempdb.dbo.result
GO
EXEC Find_Record_Across_Tables_Proc
'AdventureWorks2012', NULL, 'Employee' ,'Senior'
GO
Select * from tempdb.dbo.result
GO

search_string_in_all_tables1.2

Example 3:
To search a string in all columns of a single schema in a single table and in a single database.

Use AdventureWorks2012
GO
Delete from tempdb.dbo.result
GO
EXEC Find_Record_Across_Tables_Proc
'AdventureWorks2012', 'HumanResources', 'Employee' ,'Senior'
GO
Select * from tempdb.dbo.result
GO

search_string_in_all_tables1.1

Read Full Post »

If you are planning to convert varchar to float you should know that these two data types are not compatible with each other. In the earlier versions of SQL Server you had to use CASE, ISNUMERIC & CONVERT to convert varchar to float but in SQL Server 2012, you can do it with just one function TRY_CONVERT. Let me create a sample to explain it.

Use tempdb
GO
Create Table tbl_test
(
[Numbers] varchar(50)
)
GO
Insert into tbl_test values(12345.6789)
Insert into tbl_test values('AB12345')
Insert into tbl_test values(12.1)
Insert into tbl_test values(11.2345678)
GO

Given below are two different methods to convert varchar to float but these two methods are compatible with different versions of SQL Server.
Method 1 (For earlier versions of SQL Server):

--This script is compatible with SQL Server 2005 and above.
Use tempdb
GO
Select [Numbers],
(Case When Isnumeric([Numbers])=1 Then
Convert(float,[Numbers]) else NULL end) As [Varchar to Float]
from tbl_test
--OUTPUT

varchartofloat1.1
Method 2 (For SQL Server 2012):

--This script is compatible with SQL Server 2012 and above.
Use tempdb
GO
Select Try_convert(float,[Numbers]) as [Varchar to float]
from tbl_test
--OUTPUT

varchartofloat1.2 Cleaning :

use tempdb
GO
drop table tbl_test

Read Full Post »

How to get the Month Name from Date ? Have been questioned numerous times and we do have its solution via DATENAME function. However, today we will achieve the same solution using FORMAT function, introduced in SQL Server 2012 as well. Given below are the two methods that help in identifying the Month Name from Date in SQL Server 2005 & above as well as SQL Server 2012 & above.

Method 1 :
Script supported in SQL Server 2005 and above :

--This script will work in SQL Server 2005 and above
Declare @Datetime as datetime
Set @Datetime =getdate()

SELECT DATENAME(month, @Datetime) AS [Month Name]
--OR
SELECT DATENAME(mm, @Datetime) AS [Month Name]
--OR
SELECT DATENAME(m, @Datetime) AS [Month Name]
--OUTPUT

get month name from date1.1

Method 2 :
Script supported in SQL Server 2012 and above :

--This script will work in SQL Server 2012 and above
Declare @Datetime as datetime
Set @Datetime =getdate()
Select FORMAT(@Datetime,'MMMM') AS [Month Name]
--OUTPUT

Get month name from date-1
Have you come across any other method ? Do share.

Read Full Post »

A few days ago I was working on indexes on a development server.  Accidentally I dropped few indexes. Fortunately, since I normally take the database backup, I restored the backup and it recovered all indexes perfectly. What if I didn’t have the backup and I did it on production server, it would be just  BOOOOOM ;). However, I looked for a solution on the internet how to recover the dropped index without backup. But could not get the proper solution. So finally I decided to develop a solution which I would be sharing with you.

Note : It is recommended to take database backup on regular basis and recover any disaster from backup.

Lets create & drop one nonclustered index on a table to demonstrate it.

USE AdventureWorks2012
GO
CREATE NONCLUSTERED INDEX [IX_PurchaseOrderDetail_Sample]
ON [Purchasing].[PurchaseOrderDetail]
(
[OrderQty],
[ReceivedQty],
[RejectedQty],
[ProductID]
)
GO
DROP INDEX [IX_PurchaseOrderDetail_Sample]
ON [Purchasing].[PurchaseOrderDetail]

Lets recover it step by step :

Step 1:
In this step, you need to create the given below function in the database from where you need to do the recovery.

USE AdventureWorks2012
GO
CREATE FUNCTION [dbo].[UDF_Get_Index_Column_Name]
(@Object_id bigint,@Column_id bigint)
RETURNS varchar(Max)
AS
Begin
Declare @Column_Name as varchar(Max)
Select @Column_Name=[name] from sys.columns
where object_id =@Object_id And column_id =@Column_id
Return @Column_Name
End
GO

Step 2:
In this step, you need to create the given below stored procedure in the database from where you need to do the recovery.

CREATE PROCEDURE Recover_Dropped_Index_Proc
@Date_From DATETIME='1900/01/01',
@Date_To DATETIME ='9999/12/31'
AS

;With CTE AS (Select
Row_number() Over(Partition By A.[Transaction ID]
Order By [Transaction ID]) as [SNO]
,A.[Transaction ID]
,'CREATE ' +
(Case When Convert(int,Substring(A.[RowLog Contents 0],22,1)) =0
Then 'Heap'
When Convert(int,Substring(A.[RowLog Contents 0],22,1)) =1
Then 'Clustered'
When Convert(int,Substring(A.[RowLog Contents 0],22,1)) =2
Then 'Nonclustered'
When Convert(int,Substring(A.[RowLog Contents 0],22,1)) =3
Then 'XML'
When Convert(int,Substring(A.[RowLog Contents 0],22,1)) =4
Then 'Spatial'
When Convert(int,Substring(A.[RowLog Contents 0],22,1)) =6
Then 'Nonclustered columnstore'
end)
+ ' INDEX ' + Quotename(
Replace(Substring(
A.[RowLog Contents 0],47,LEN(A.[RowLog Contents 0])),0x00,0x))
+' ON ' + Sch.name +'.'
+ Object_Name(
Convert(varbinary,Reverse(Substring(A.[RowLog Contents 0],5,4))))
as [Command1]

, [dbo].[UDF_Get_Index_Column_Name] (
Convert(bigint,
Convert(varbinary,Reverse(Substring(A.[RowLog Contents 0],5,4))))
, Convert(bigint
, Convert(varbinary,Substring(A.[RowLog Contents 0],20,2))))
as [Column Name]

, Convert(int,Substring(A.[RowLog Contents 0],22,1)) as [Type]

, SUM(1) OVER(Partition By A.[Transaction ID]) as [Total Rows]

From sys.fn_dblog(NULL, NULL) As A
Inner Join sys.tables As tbl
On Object_Name(Convert
(varbinary,Reverse(Substring(A.[RowLog Contents 0],5,4))))=tbl.name
Inner Join sys.schemas As Sch On tbl.schema_id =sch.schema_id
Where A.AllocUnitName In ('sys.sysiscols.clst','sys.sysidxstats.clst')
And Context In ('LCX_MARK_AS_GHOST', 'LCX_HEAP')
And Operation in ('LOP_DELETE_ROWS')
And A.[TRANSACTION ID] In (SELECT DISTINCT [TRANSACTION ID]
FROM  sys.fn_dblog(NULL, NULL)
Where Context IN ('LCX_NULL') And Operation In ('LOP_BEGIN_XACT')
And [Transaction Name] Like '%DROP INDEX%'
And  CONVERT(NVARCHAR(11),[Begin Time]) Between @Date_From And @Date_To)
)
Select (Case When [type]=0 And [SNo] =2 And [SNO]<>[Total rows]
Then '(' + [Column Name] +','
When [type]=0 And [SNo] =2 And [SNO]=[Total rows]
Then '(' + [Column Name] +')'
When [type]=0 And [SNo] >2 And [SNO]<>[Total rows]
Then  [Column Name] + ','
When [type]=0 And [SNo] >2 And [SNO]=[Total rows]
Then  [Column Name] + ')'
else Command1 end) AS [Text] from CTE
GO

Step 3 :
In this step, you need to execute the above stored procedure to recover the dropped index. Given below is the syntax.
You must supply the correct recovery dates to the stored procedure to recover proper records.

USE AdventureWorks2012
GO
EXEC [Recover_Dropped_Index_Proc] '2013/04/01','9999/12/31'
--OUTPUT

recover_dropped_index1.1

Step 4 :
Just copy the above result set and paste in the query window and execute it using correct database and you will get your indexes back in your database.

Read Full Post »

ColumnStore Index & Forceseek table hints enhancements are two new features introduced in SQL Server 2012. The error message we will discuss today is related to these two enhancements because they both cannot be used together.

Let’s discuss this in detail:

Message Number: 366

Severity : 16

Error Message: The query processor could not produce a query plan because the FORCESEEK hint on table or view ‘%.*ls’ cannot be used with the column store index ‘%.*ls’.

Error Generation:
Let me create a sample to demonstrate this error.

--First Create a columnstore index on [Purchasing].[PurchaseOrderDetail]
USE [AdventureWorks2012]
GO
CREATE NONCLUSTERED COLUMNSTORE INDEX [IX_PurchaseOrderDetail_ColumnStore]
ON [Purchasing].[PurchaseOrderDetail]
(
[ReceivedQty],
[ProductID]
)
WITH (DROP_EXISTING = OFF) ON [PRIMARY]
GO

--Try to use it with FORCESEEK table hint

Select * from [Purchasing].[PurchaseOrderDetail]
WITH (FORCESEEK,INDEX (IX_PurchaseOrderDetail_ColumnStore))
--OUTPUT

Msg 366, Level 16, State 1, Line 1
The query processor could not produce a query plan because the FORCESEEK hint on table or view ‘PurchaseOrderDetail’ cannot be used with the column store index ‘IX_PurchaseOrderDetail_ColumnStore’.

Ooopps…… I am unable to execute it.

Resolution:

The reason behind this error is that we cannot use COLUMNSTORE INDEX with FORCESEEK table hint because columnstore index already boosted the performance of the query on that particular table. So, we do not use any further FORCESEEK table hints on that table. But sometime we create columnstore index on some other fields and we need to do forceseek on some other fields, so in that case we can create another non cluster index and point it to forceseek table hint.

Give below are the script.

--Create a new noncluster index BUT NOT COLUMNSTORE INDEX
CREATE NONCLUSTERED INDEX [IX_PurchaseOrderDetail_Sample] ON [Purchasing].[PurchaseOrderDetail]
(
[ReceivedQty],
[ProductID]
)
WITH (DROP_EXISTING = OFF) ON [PRIMARY]
GO

--Execute the query against the index
Select * from [Purchasing].[PurchaseOrderDetail]
WITH (FORCESEEK,INDEX (IX_PurchaseOrderDetail_Sample))
Where ProductID>2 And ReceivedQty>5
--OUTPUT

error366.1.1

Conclusion :
Remember, whenever you FORCESEEK with index, make sure that the index is not a columnstore index. However, if you need to use FORCESEEK table hint with index on the same table, you can create another index without columnstore and use it in FORCESEEK.

Clean Database :
Execute the given below script to drop the sample indexes.

DROP INDEX [IX_PurchaseOrderDetail_ColumnStore]
ON [Purchasing].[PurchaseOrderDetail]
DROP INDEX [IX_PurchaseOrderDetail_Sample]
ON [Purchasing].[PurchaseOrderDetail]

Read Full Post »

sys.dm_os_memory_cache_counters is one of the dynmaic management views shipped with SQL Server 2005. The major benefits of this dynamic management view is to provide the list of summary stating how cache is allocated against each request.

Given below is a simple query that will give the details about cache.

--This query is compatibale with SQL Server 2005 and 2008 only.
Select [name],[type],SUM([single_pages_kb]) As [single_pages_kb]
,SUM([multi_pages_kb]) As [multi_pages_kb]
from  sys.dm_os_memory_cache_counters
Group By [name],[type]
Order By [name], [type]
--OUTPUT

dm_os_memory_cache_counters1.1

A few days ago I tried using the same query in SQL Server 2012 to check out the summary of cache but the above query did not work. Given below is the error detail.

Select [name],[type]
,SUM([single_pages_kb]) As [single_pages_kb]
,SUM([multi_pages_kb]) As [multi_pages_kb]
from  sys.dm_os_memory_cache_counters
Group By [name],[type]
Order By [name], [type]
--OUTPUT

Msg 207, Level 16, State 1, Line 2
Invalid column name ‘single_pages_kb’.
Msg 207, Level 16, State 1, Line 3
Invalid column name ‘multi_pages_kb’.
sys.dm_os_memory_cache_counter1.2

Oooops……………
It generated an error. The first impression I got was that these two fields have been eliminated from sys.dm_os_memory_cache_counters in SQL Server 2012 ?

But the answer is No, these field are not eliminated but renamed. Given below are the details.


S.No


Previous Column Name


New Column Name

1

single_pages_kb

pages_kb

2

multi_pages_kb

pages_in_use_kb

Lets rename the column in the above query and execute it again in SQL Server 2012.

--This query is compatible with SQL Server 2012 and above.
Select [name],[type]
,SUM([pages_kb]) As [pages_kb]
,SUM([pages_in_use_kb]) As [pages_in_use_kb]
from sys.dm_os_memory_cache_counters
Group By [name],[type]
Order By [name], [type]
--OUTPUT

sys.dm_os_memory_cache_counter1.3

Conclusion :
In SQL Server 2012, sys.dm_os_memory_cache_counters has renamed the two columns single_pages_kb, multi_pages_kb to pages_kb, pages_in_use_kb respectively. Remember to implement this renamed column change effects to avoid such errors.

Reference : MSDN

Read Full Post »

Sometimes, you feel very handicapped when you need to convert some complex data types but due to compatibility, the built-in conversion functions such as Cast, Convert, Try_Cast, Try_Convert cannot aid conversion.

How to convert float to varchar is indeed an old topic. In this article, we will solve this issue via STR function and FORMAT function introduced in SQL Server 2012.

Given below are the two methods to convert float to varchar.

Method 1:
In this method, we will use STR function to convert float to varchar and thereafter LTRIM to trim the extra spaces left in it.

--This script is compatible with SQL Server 2005 and above.
Declare @varchar as varchar(50)
Declare @float as float

Set @float =1234567.12345678
Select @float as [Float]

Set @varchar =LTRIM(STR(@float,50,8))
Select @varchar as [Float converted to varchar]
--OUTPUT

Convertfloortovarchar1.1

Method 2:
In the above method, you can notice that we used two different methods (STR, LTRIM) to convert float to varchar and to trim extra spaces. In this method we will use ONLY FORMAT function to convert float to varchar.

--This script is compatible with SQL Server 2012 and above.
Declare @varchar as varchar(50)
Declare @float as float

Set @float =1234567.12345678
Select @float as [Float]

Set @varchar =Format(@float,'#.#############')
Select @varchar as [Float converted to varchar]
--OUTPUT

convertfloattovarchar1.2

Read Full Post »

“How to find the SQL Server port number ?” has been an old topic being discussed in multiple forums. The common solution provided is using xp_instance_regread. It is one of the useful undocumented stored procedures when you need to read registry settings. In this article, I will give you two solutions. First one using xp_instance_regread and second, using sys.dm_server_registry, a new dynamic management view shipped in SQL Server 2008 R2

Method 1 : Using xp_instance_regread.
In this method we will use xp_instance_regread to find the port number.

--This script will work on SQL Server 2005 and above
DECLARE @HkeyLocal nvarchar(18)
Declare @Instance varchar(100)
DECLARE @MSSqlServerRegPath nvarchar(200)
DECLARE @PortNumber nvarchar(100)

SET @Instance ='MSSQL11.MSSQLSERVER'
SET @HkeyLocal=N'HKEY_LOCAL_MACHINE'
SET @MSSqlServerRegPath=N'SOFTWARE\Microsoft\\Microsoft SQL Server\'
+ @Instance + '\MSSQLServer\SuperSocketNetLib\Tcp\IPAll'

Print @MSSqlServerRegPath
EXEC xp_instance_regread @HkeyLocal
, @MSSqlServerRegPath
, N'TcpPort'
, @PortNumber OUTPUT
SELECT @PortNumber as [Port Number]
--OUTPUT

Port Number
————
1433

(1 row(s) affected)

Method 2 : Using using sys.dm_server_registry.
In this method we will use sys.dm_server_registry to find the port number.

--This script will work on SQL Server 2012 and above
Use master
GO
Select value_data as [Port Number]
From sys.dm_server_registry
Where registry_key like '%IPALL%' and
value_name ='TcpPort'

Port Number
————
1433

(1 row(s) affected)

Conclusion :
If you compare both methods, you will feel the difference, because the code is much optimized in the second method. Also, you can utilize the result set of second method further without using any temporary table but on the other hand you need temporary table to utilize the result set further.

Read Full Post »

How to get the day of the week ? I have been asked this question several times and we do have its solution via DATENAME function. However today we will achieve the same solution using FORMAT function, introduced in SQL Server 2012 as well. Given below are the two methods that help in identifying the day of a week in SQL Server 2005 & SQL Server 2012 respectively.
Method 1 :
Script supported in SQL Server 2005 and above :

--This script will work in SQL Server 2005 and above
Declare @Datetime as datetime
Set @Datetime =getdate()
Select DATENAME(dw , @Datetime) as [Weekday Name]
--OR
Select DATENAME(weekday, @Datetime) as [Weekday Name]
--OUTPUT

Get week day name1.1

Method 2 :
Script supported in SQL Server 2012 and above :

--This script will work in SQL Server 2012 and above
Declare @Datetime as datetime
Set @Datetime =getdate()
Select FORMAT(@Datetime,'dddd') as [Weekday Name]
--OUTPUT

Get week day name1.2

Have you come across any other method ? Do share.

Read Full Post »

« Newer Posts - Older Posts »