Below is a quick code snippet example you can reuse to replace multiple words within a string using python.
s = "The quick brown fox jumps over the lazy dog" print(s) for r in (("brown", "red"), ("lazy", "quick")): s = s.replace(*r) print(s)
Below is a quick code snippet example you can reuse to replace multiple words within a string using python.
s = "The quick brown fox jumps over the lazy dog" print(s) for r in (("brown", "red"), ("lazy", "quick")): s = s.replace(*r) print(s)
You’re probably never going to be familiar with every database object, i.e. Table, View, Stored Procedure and Function, that exists in a large production database, even if you were the one who designed it. So everyone who maintains an environment be it a call center back end or sales system back end or CRM back end etc. etc. needs to be able to locate objects quickly.
Redgate offer a fantastic free tool to do this within SQL Server Management Studio through a GUI called SQL Search.
As great as this is though sometimes you might want to search through object definitions programmatically.
To clarify I’m defining object definition as being column names of a table or view or the command that makes up a stored procedure or function.
Below is the Store Procedure I’ve written to do this called SearchObjectDefinition. To work this Stored Procedure also requires the User Defined Function (UDF) called Split which I used in the tutorial “How to pass a multi-value parameter to a stored procedure from a SSRS Report“.
Below are a few use cases for SearchObjectDefinition:
--List All Instance Tables, Stored Procedures, Views and Functions EXEC dbo.SearchObjectDefinition --List All Stored Procedures, and Functions in the Databases --TestDatabaseOne and TestDatabaseTwo EXEC dbo.SearchObjectDefinition @ObjectType = 'Sp, Fn' ,@DatabaseName = 'TestDatabaseOne, TestDatabaseTwo' --List All Instance Tables, Stored Procedures, Views and Functions --where Object Definition contains the word Insert EXEC dbo.SearchObjectDefinition @strFind = 'insert' --List All Instance Tables where Object Name is Customers and --Column name contains the word Phone EXEC dbo.SearchObjectDefinition @ObjectType = 'tb' ,@ObjectName = 'Customers' ,@strFind = 'Phone'
As always be sure to deploy the following Function and Store Procedure in a utility database not the master database as this is bad practice.
Split Function:
--USE [DatabaseName]; --GO IF OBJECT_ID('[Split]') IS NULL EXEC ('CREATE FUNCTION dbo.[Split](@i INT) RETURNS @RtnValue TABLE (j INT) AS BEGIN INSERT INTO @RtnValue (j) SELECT 1 RETURN END'); GO ALTER FUNCTION [dbo].[Split] ( @List NVARCHAR(2000) ,@SplitOn NVARCHAR(5) ) RETURNS @RtnValue TABLE ( Id INT identity(1, 1) ,Value NVARCHAR(100) ) AS BEGIN WHILE (Charindex(@SplitOn, @List) > 0) BEGIN INSERT INTO @RtnValue (value) SELECT Value = ltrim(rtrim(Substring(@List, 1, Charindex(@SplitOn, @List) - 1))) SET @List = Substring(@List, Charindex(@SplitOn, @List) + len(@SplitOn), len(@List)) END INSERT INTO @RtnValue (Value) SELECT Value = ltrim(rtrim(@List)) RETURN END
SearchObjectDefinition Stored Procedure:
--USE [DatabaseName]; --GO IF OBJECT_ID('[SearchObjectDefinition]') IS NULL EXEC ('CREATE PROCEDURE dbo.[SearchObjectDefinition] AS SELECT 1') GO ALTER PROCEDURE [dbo].[SearchObjectDefinition] ( @ObjectType AS VARCHAR(20) = NULL ,@ObjectName AS SYSNAME = NULL ,@DatabaseName AS SYSNAME = NULL ,@strFind AS VARCHAR(MAX) = NULL ) AS BEGIN SET NOCOUNT ON; SET @strFind = ISNULL(@strFind, '') SET @ObjectName = ISNULL(@ObjectName, '') IF OBJECT_ID('tempdb..#Result') IS NOT NULL DROP TABLE #Result; DECLARE @DatabaseTable TABLE (DbName SYSNAME) DECLARE @DbName AS SYSNAME DECLARE @Sql AS VARCHAR(MAX) CREATE TABLE #Result ( DbName SYSNAME NULL ,ObjectType VARCHAR(2) ,ObjectName SYSNAME ,ObjectDefinition VARCHAR(MAX) ) IF @DatabaseName IS NOT NULL BEGIN INSERT INTO @DatabaseTable (DbName) SELECT Value FROM dbo.Split(@DatabaseName, ',') END IF @DatabaseName IS NULL BEGIN INSERT INTO @DatabaseTable (DbName) SELECT NAME FROM master.dbo.sysdatabases WHERE NAME NOT IN ( 'tempdb' ,'master' ,'msdb' ,'model' ) ORDER BY NAME ASC END SET @DbName = '' --TO FIND STRING IN ALL PROCEDURES IF @ObjectType LIKE '%Sp%' OR @ObjectType IS NULL BEGIN WHILE @DbName IS NOT NULL BEGIN SET @DbName = ( SELECT MIN(DbName) FROM @DatabaseTable WHERE DbName > @DbName ) SET @Sql = ' USE ' + QUOTENAME(@DbName) + '; INSERT INTO #Result ( DbName ,ObjectType ,ObjectName ,ObjectDefinition ) SELECT ''' + @DbName + ''' AS DbName ,''Sp'' AS ObjectType ,OBJECT_NAME(OBJECT_ID) AS ObjectName ,OBJECT_DEFINITION(OBJECT_ID) AS ObjectDefinition FROM ' + QUOTENAME(@DbName) + '.sys.procedures WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE ''%'' + ''' + @strFind + ''' + ''%'' AND Name LIKE ''%'' + ''' + @ObjectName + ''' + ''%'' ' EXEC (@Sql) END END SET @DbName = '' --TO FIND STRING IN ALL VIEWS IF @ObjectType LIKE '%Vw%' OR @ObjectType IS NULL BEGIN WHILE @DbName IS NOT NULL BEGIN SET @DbName = ( SELECT MIN(DbName) FROM @DatabaseTable WHERE DbName > @DbName ) SET @Sql = ' USE ' + QUOTENAME(@DbName) + '; INSERT INTO #Result ( DbName ,ObjectType ,ObjectName ,ObjectDefinition ) SELECT ''' + @DbName + ''' AS DbName ,''Vw'' AS ObjectType ,OBJECT_NAME(OBJECT_ID) AS ObjectName ,OBJECT_DEFINITION(OBJECT_ID) AS ObjectDefinition FROM ' + QUOTENAME(@DbName) + '.sys.VIEWS WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE ''%'' + ''' + @strFind + ''' + ''%'' AND Name LIKE ''%'' + ''' + @ObjectName + ''' + ''%'' ' EXEC (@Sql) END END SET @DbName = '' --TO FIND STRING IN ALL FUNCTION IF @ObjectType LIKE '%Fn%' OR @ObjectType IS NULL BEGIN WHILE @DbName IS NOT NULL BEGIN SET @DbName = ( SELECT MIN(DbName) FROM @DatabaseTable WHERE DbName > @DbName ) SET @Sql = ' USE ' + QUOTENAME(@DbName) + '; INSERT INTO #Result ( DbName ,ObjectType ,ObjectName ,ObjectDefinition ) SELECT ''' + @DbName + ''' AS DbName ,''Fn'' AS ObjectType ,ROUTINE_NAME AS ObjectName ,ROUTINE_DEFINITION AS ObjectDefinition FROM ' + QUOTENAME(@DbName) + '.INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_DEFINITION LIKE ''%'' + ''' + @strFind + ''' + ''%'' AND ROUTINE_NAME LIKE ''%'' + ''' + @ObjectName + ''' + ''%'' AND ROUTINE_TYPE = ''FUNCTION'' ORDER BY ROUTINE_NAME ' EXEC (@Sql) END END SET @DbName = '' --TO FIND STRING IN ALL TABLES OF DATABASE. IF @ObjectType LIKE '%Tb%' OR @ObjectType IS NULL BEGIN WHILE @DbName IS NOT NULL BEGIN SET @DbName = ( SELECT MIN(DbName) FROM @DatabaseTable WHERE DbName > @DbName ) SET @Sql = ' USE ' + QUOTENAME(@DbName) + '; INSERT INTO #Result ( DbName ,ObjectType ,ObjectName ,ObjectDefinition ) SELECT ''' + @DbName + ''' AS DbName ,''Tb'' AS ObjectType ,t.NAME AS ObjectName ,c.NAME AS ObjectDefinition FROM ' + QUOTENAME(@DbName) + '.sys.tables AS t INNER JOIN ' + QUOTENAME(@DbName) + '.sys.columns c ON t.OBJECT_ID = c.OBJECT_ID WHERE c.NAME LIKE ''%'' + ''' + @strFind + ''' + ''%'' AND t.Name LIKE ''%'' + ''' + @ObjectName + ''' + ''%'' ORDER BY [ObjectDefinition] ASC ' EXEC (@Sql) END END SELECT DbName ,ObjectType ,ObjectName ,ObjectDefinition FROM #Result ORDER BY DbName ASC ,ObjectType ASC ,ObjectName ASC DROP TABLE #Result END
The ‘String or binary data would be truncated’ error will occur if an insert or update statement is trying to put too many characters into a field, defined in a table, which has been assigned too few character spaces. For example trying to write an email address with 255 characters into a table where the column email has been assigned 40 characters.
The easy fix is assign more characters to the column or columns you have determined are experiencing the problem. The more complicated but potentially necessary fix might be to change the logic or introduce validation at the source of data entry.
Finding the columns experiencing the problems however can be time consuming.
( . . . without the little script below of course)
SQL Server will kindly direct you to the stored procedure or insert/update statement that is experiencing the problem. However it will not pin point the exact column or columns that cannot be written to. The pain then is determining where the data won’t fit.
To speed things up take the entire query or query section you know to be causing the problem and write the results it into a temp table called #temp, i.e. SELECT * INTO #temp FROM SomeTable
Once the data has been written to the temp table #temp run the scrip below in the same window.
DECLARE @sql VARCHAR(MAX) SET @sql = ( SELECT ( SELECT ',MAX(LEN(' + NAME + ')) AS [' + NAME + ']' FROM tempdb.sys.columns WHERE object_id = object_id('tempdb..#temp') FOR XML PATH('') ) ) SET @sql = 'SELECT ' + RIGHT(@sql, LEN(@sql) - 1) + ' FROM #temp' EXEC (@sql)
Often data is entered into the database as a string (varchar), when a more appropriate data type should have been applied.
Here’s a snippet of T-SQL for dealing with datetime data, stored as varchar, when what you really need is the hour.
DECLARE @DateTime AS VARCHAR(25) -- GET THE CURRENT DATETIME AND CONVERT INTO A STRING SET @DateTime = ( SELECT CONVERT(VARCHAR(25), GETDATE(), 120) ) --PRINT @DateTime -- GET HOUR FROM DATETIME AS A STRING SELECT DATEPART(HOUR, CONVERT(DATETIME, CONVERT(VARCHAR(13), @DateTime, 120) + ':00')) AS ConvertedHour
Why would data be stored as a varchar instead of using the appropriate data type in the first place?
The most common reason might be that XML files have been loaded without any data type conversions being applied, i.e. dates have been entered as strings along with everything else.
Why would you need this code?
Should you be confronted with data in this raw string form you would be unable to apply a clause regarding a specific hour. Ideally there should be some sort of staging table to convert the fields into the appropriate data types but if you simply wanted to apply some clauses to select specific data, which will be outputted to an excel file for example, that additional effort may be unnecessary.