Find all instances of a string within a string in T-SQL

CREATE FUNCTION dbo.FindPatternLocation
(
    @string NVARCHAR(MAX),
    @term   NVARCHAR(255)
)
RETURNS TABLE
AS
    RETURN 
    (
      SELECT pos = Number - LEN(@term) 
      FROM (SELECT Number, Item = LTRIM(RTRIM(SUBSTRING(@string, Number, 
      CHARINDEX(@term, @string + @term, Number) - Number)))
      FROM (SELECT ROW_NUMBER() OVER (ORDER BY [object_id])
      FROM sys.all_objects) AS n(Number)
      WHERE Number > 1 AND Number <= CONVERT(INT, LEN(@string)+1)
      AND SUBSTRING(@term + @string, Number, LEN(@term)) = @term
    ) AS y);
Simply use the function above.

If you want to understand technically how this works, see the reference below.

Essentially, this function dynamically creates a table (CTE) of the term being searched for with Number being the Row_Number of each charindex within the string.

This CTE is then searched to elicit the starting positions of each location where string term matches ([WHERE] SUBSTRING(@term + @string, Number, LEN(@term)) = @term).

Usage:




The part: "SELECT ROW_NUMBER() OVER (ORDER BY [object_id].." is there to provide space to establish the CTE with which to store search string indexes. If you need more space to traverse over (your search string is > 2k characters) you can use sys.all_columns instead of sys.all_objects or a CROSS JOIN for tables with greater than 8k records.


Reference: https://sqlperformance.com/2013/01/t-sql-queries/generate-a-set-1

All credits: Aaron Bertrand. He is a T-SQL genius. If it can be done in T-SQL, Aaron has done it, benchmarked it and probably blogged about it: https://sqlperformance.com/author/abertrand

Visual Studio Config Transforms

When you are working on software that needs to target different resources for different environments (ie. local, DEV, STAGE, PRODUCTION), you can easily manage your VS project environment through the use of .config transformation files.

Here is your default web.config:



Simply make an alternate version (with the same name) of the element you wish to change in your various configuration transformations (web.DEBUG.config, web.Development.config, etc.). In this example, we are setting up a transform to change the connection string that has the name, "applicationConnStr":



NOTE: The same configuration element (the same name, specifically) you want to transform must be in the base web.config file.

By default, the transformation we have set up will only be applied when the project is published. In order to get the transformations working with each build, you must edit the bottom of the *.csproj file with the following Target:

  <Target Name="BeforeBuild">
    <TransformXml 
        Source="Web.Base.config" 
        Transform="Web.$(Configuration).config" 
        Destination="Web.config" />
  </Target>



And be sure to uncomment the code, it is commented out by default. Now select a different build configuration, build your project, and you should see the "applicationConnStr" transformed to match the element from the web.config.[Debug||Release||etc.] that you selected to Build:




To add new web.config transform files, just right click on the web.config file and select "Add Config Transformation".



To associate your transformations with different builds, under the Build Dropdown, select "Configuration Manager..." and configure as you like:




Setting up build configurations that point to different web.configs (actually web.config "transforms") allows you to debug and run code according to your needs (ie. show DEMO at a meeting, Debug Development to uncover a bug, point to local for ongoing development, etc.).

ASP.NET Core has a very different configuration setup that uses JSON objects and more configurable things in .NET Core Startup.cs; this reference is for .NET Standard.

The key in all of this is the name of the element you are matching and then replacing. It just has to match in both places and all will be transformed on your application's web.config. In this example, we matched and replaced the value for a config element with the name, "applicationConnStr".

In a real-world scenario, there are many things that we could dynamically replace through config transforms: database connection strings, image servers, mail servers, file shares, printer locations, encryption keys, etc.).

Reference: https://docs.microsoft.com/en-us/aspnet/web-forms/overview/deployment/visual-studio-web-deployment/web-config-transformations

Customize SSRS Stylesheet

This is an easy thing to do, especially if you are well-versed in CSS/DOM designing.

1). Go to this location and open up HtmlViewer.css in your favorite text editor:




2). Edit/override styles however you see fit. You can change almost all of the styles on the SSRS toolbar:

(before)

(change made)

(after)

3). If you want to point to different stylesheets for different report executions (ie. if you need security and want to hide the Save or Print button from some users), you can easily do that by adding the filename of your own custom stylesheet to the rc:Stylesheet parameter in the SSRS Request URI a la:


Other things like client-side scripting can be done to extend the Report Viewer UI further, but doing that sort of "functionality" integration is not well documented. If you want complete control over your Reporting Services app UI, take a look at the Report Server web service: https://docs.microsoft.com/en-us/sql/reporting-services/report-server-web-service/report-server-web-service

Happy Reporting!