Technical Insights: Azure, .NET, Dynamics 365 & EV Charging Architecture

Category: SQL Server Page 3 of 4

SQL Server Category

Linq.Binary(SQL Image Data Type) Type to File Stream

I got a column with Data Type of Image in SQL Server. What I would like to do is to omit this data to a FileStream or to a file. I tried to read the data using LINQ and I found the data type detected for that particular column is System.Data.Linq.Binary. I was expecting it to be Byte Data type. So I need to convert the Binary to byte then to File Stream. But I found a simpler way by using “ToArray” properties and cast it back to byte solves my problem.

    foreach (tblExpReceiptFile file in ExpReceiptFactory.tblExpReceiptFileSelect())
            {
                string fileName = file.vcFileName.Replace(" ","_");
                FileStream fileStream = File.Create(DirectoryPath + @"\" + fileName + ".pdf");
                fileStream.Write((byte[])file.imgFileContent.ToArray(), 0, ((byte[])file.imgFileContent.ToArray()).Length);
                fileStream.Close();
            }

SQL Methods in LINQ

I’m trying to implement DateDiff in LINQ. I would like to get all records with the same date and ignoring the timestamp.

Here is my code snippet which doesn’t work

 public int tblExpReceiptFileUniqueID(string chCreateStaffCode, string vcFileName,
                                                long intFileSize, DateTime? sdCreateDate)
        {
            var expReceiptFile = from ef in DataContext.tblExpReceiptFiles orderby ef.intFileID
                                 where ef.chCreateStaffCode == chCreateStaffCode
                                 && ef.vcFileName == vcFileName
                                 && ef.bintFileSize == intFileSize
                                 && ((DateTime)ef.sdCreateDate).Date == sdCreateDate.Value.Date
                                 select ef;

            tblExpReceiptFile expReceiptFileRec = expReceiptFile.First();

            return expReceiptFileRec.intFileID;
        }

I’m trying to cast the column to “DateTime” and use the “Date” property but I got this error
“The Member ‘System.DateTime.Date’ has no supported translation to SQL”

I thought of “DATEDIFF” function in SQL server and I’m trying to get my head around in implementing this using LINQ and I found that we can use a library called “SQLClient”

using System.Data.Linq.SqlClient;

Code Snippet which is working

    public int tblExpReceiptFileUniqueID(string chCreateStaffCode, string vcFileName,
                                                long intFileSize, DateTime? sdCreateDate)
        {
            var expReceiptFile = from ef in DataContext.tblExpReceiptFiles orderby ef.intFileID
                                 where ef.chCreateStaffCode == chCreateStaffCode
                                 && ef.vcFileName == vcFileName
                                 && ef.bintFileSize == intFileSize
                                 && SqlMethods.DateDiffDay(ef.sdCreateDate, sdCreateDate.Value.Date) == 0
                                 select ef;

            tblExpReceiptFile expReceiptFileRec = expReceiptFile.First();

            return expReceiptFileRec.intFileID;
        }

Check Existence of temp table in memory

How to check whether the temp table is exists on the memory or not?The reason why you need this is because your stored procedure can throw the error when you try to drop a temp table which is not exists anymore on the memory. The best practice to drop a temp table is normally to check the existence of the table on the memory then we drop the table if it is exists

--Drop the table after usage
IF object_id('tempdb..#tmpStandardCostRate') IS NOT NULL
BEGIN
   DROP TABLE #tmpStandardCostRate
END

Find Index in all the tables SQL Server

This is a query to find all the indexes in your table including when it was last updated

Find all indexes on all tables

SELECT
	OBJECT_NAME(OBJECT_ID) AS 'Table Name',
	[name] as 'Statistic',
	STATS_DATE(object_id, index_id) AS 'Last Updated Statistics Date'
FROM
	sys.indexes
ORDER BY
	 STATS_DATE(object_id, index_id)
DESC

Find all indexes on a particular table

SELECT
	OBJECT_NAME(OBJECT_ID) AS 'Table Name',
	[name] as 'Statistic',
	STATS_DATE(object_id, index_id) AS 'Last Updated Statistics Date'
FROM
	sys.indexes
WHERE
        OBJECT_NAME(OBJECT_ID)  = 'YourTableName'

This SQL query returning the information about number of rows in the table as well as number of update/insert/delete after the last index has been rebuilt

SELECT
	'TABLE ' = substring(sysobjects.name,1,30) , ' INDEX ' = substring(sysindexes.name,1,30)
	,sysIndexes.rowcnt, sysindexes.rowmodctr
	,[last updated]=STATS_DATE(sysobjects.id, sysindexes.indid)
        ,user_seeks,user_scans,user_lookups,user_updates
FROM	sysobjects
INNER JOIN sysindexes ON sysobjects.id = sysindexes.id  AND sysindexes.indid > 0
INNER JOIN sys.dm_db_index_usage_stats iusage ON iusage.object_id = sysobjects.id  AND iusage.index_id = sysindexes.indid
WHERE
	sysobjects.xtype = 'U'
AND
	iusage.database_id = (SELECT dbid FROM master.dbo.sysdatabases WHERE [name] = db_name())
ORDER BY sysobjects.name

CSV parsing in SQL server

I’ve got this SQL Function to parse comma separated value into a table. We need this function when our application commit separated comma value in a text. We normally do this when we want to send an array of value to the SQL server

CREATE FUNCTION [dbo].[SplitCSV](@CSV text)
-- Returns a table with txtValue column
RETURNS @OutTable table(txtValue text)
AS
BEGIN

declare @currentposition int
declare @nextposition    int
declare @lengthOfString  int

-- Assign the starting position of the string
SET @currentposition = 0
 -- The reason for this is to force entrance into the while loop below.
SET @nextposition = 1

WHILE @nextposition > 0
BEGIN
-- Assign the next position to be the current index of ',' + 1
SELECT @nextposition = charindex(',', @CSV, @currentposition + 1)

-- In here we need to find 2 things. The position of the ','
-- and the length of the string segment in between.
SELECT @lengthOfString = CASE WHEN @nextposition > 0
       THEN @nextposition
       ELSE DATALENGTH(@CSV) + 1
       END - @currentposition - 1

--After the length and position is found all we need to do
--is take the substring of the string passed in.
INSERT @OutTable (txtValue)
       VALUES (substring(@CSV, @currentposition + 1, @lengthOfString))

--Set the current position to the next position
SELECT @currentposition = @nextposition
END
RETURN
END

Usage in SQL Query

SELECT
	VenueID
FROM
	Venues
WHERE
	PostCode
IN
	(SELECT CAST(txtValue as VarChar) FROM dbo.splitcsv(@PostCode))

Dynamic Order By in ROW_NUMBER()

How to do order by in your paging using ROW_NUMBER() feature on SQL Server 2005

SELECT a.CurrentPrice, a.LotQuantity, a.IsAuction,
	a.AuctionID, a.AuctionName, a.DateStart, a.DateFinish,
	a.StartingPrice, a.ReservePrice, a.FixedPrice, a.BidIncrement,
	p.ProductID, p.CategoryID, p.BrandID, p.ProductName, p.ContentID, p.ThumbImageID,
	Row_Number() OVER
	(
		ORDER BY
		CASE
			WHEN @OrderBy = 'Price_ASC'	THEN CurrentPrice
			WHEN @OrderBy = 'ClosingSoon_ASC'	THEN ISNULL(DateFinish, DATEADD(DAY, 100, GETDATE()))
		END ASC,
		CASE
			WHEN @OrderBy = 'Price_DESC'		THEN CurrentPrice
			WHEN @OrderBy = 'ClosingSoon_DESC'	THEN ISNULL(DateFinish, DATEADD(DAY, 100, GETDATE()))
		END DESC,
		CASE
		       WHEN @OrderBy = 'Name_ASC'			THEN AuctionName
		END ASC,
		CASE
		       WHEN @OrderBy = 'Name_DESC'			THEN AuctionName
		END DESC
		) AS RowNum
FROM Auction a
	INNER JOIN Products p ON a.ProductID = p.ProductID
	INNER JOIN [Content] c ON p.ContentID = c.ContentID

Using Transaction Scope on .NET

Basic Requirements:

1. Have the MSDTC(Distributed Transaction Coordinator) windows service running on your machine
2. Be talking to a SQL 2000 or 2005 Database configured likewise
3. Run this registry script to fix the windows XP SP2 that was causing MSDTC to fail (save as “.reg”)

Registry Script

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\RPC]
"RestrictRemoteClients"=dword:00000000

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Rpc\Internet]
"Ports"=hex(7):31,00,30,00,32,00,35,00,2d,00,31,00,30,00,35,00,35,00,00,00,00,\
  00
"PortsInternetAvailable"="Y"
"UseInternetPorts"="Y"

You can create a class/library to wrap the transaction code
Code:

using System;
using System.Data;
using System.Transactions;

namespace BusinessLayer
{
    public class TransactionScopeWrapper : IDisposable
    {
        private TransactionScope _scope = null;

        public TransactionScopeWrapper()
        {
            if (ConfigHelper.UseTransactionScope)
            {
                int timeout = ConfigHelper.TransactionTimeoutMinutes;

                if (timeout == int.MinValue)
                {
                    timeout = 10;
                }

                _scope = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, timeout, 0));
            }
        }

        public void Complete()
        {
            if (_scope != null)
            {
                _scope.Complete();
            }
        }

        #region IDisposable Members

        public void Dispose()
        {
            if (_scope != null)
            {
                _scope.Dispose();
            }
        }

        #endregion
    }
}

Usage of the wrapper:

public void CancelAuction(int auctionid)
        {
            using (TransactionScopeWrapper scope = new TransactionScopeWrapper())
            {
                tdsAuction.AuctionDataTable auctionTable = AuctionAdapter.AuctionSelect(auctionid);

                if (auctionTable.Rows.Count > 0)
                {
                    tdsAuction.AuctionRow auctionRow = auctionTable.Rows[0] as tdsAuction.AuctionRow;

                    auctionRow.AuctionStatusID = (int)AuctionStatusEnum.Cancelled;
                    AuctionAdapter.Update(auctionRow);

                    // return the Stock to inventory
                    if (auctionRow.IsAuction)
                    {
                        InventoryData.InventoryReturnLotsCancelAuction(auctionid);
                    }
                    else
                    {
                        InventoryData.InventoryReturnLotsForDeal(auctionid);
                    }
                }

                scope.Complete();
            }
        }

Paging through strored procedure in sql server

This is very important for the most web developers. This stored procedure accept parameter of page index and page size. By using this paging, you don’t need to store everything in your viewstate which in the end will cause performance suffer. This will load up the necessary result based on the page index and page size and it uses row number to put the number in each row.

Datagrid needs to use custom paging = true as well as virtualitem count to produce the number for paging.

Datagrid in ASPX Page


            
                
                
                
                    
                    
                    
                    
                    
                    
                
                
                
            

Code Behind

//function to do the paging itself
  private void LoadContent(int pageIndex)
    {
        _presenter.GetContentSubmissionSelect(pendingStatusID, pageIndex, PAGE_SIZE);

        if (GetContentSubmissionSelect.Rows.Count > 0)
        {
            lblNoContent.Visible = false;

            dgTaskList.Visible = true;
            dgTaskList.AllowCustomPaging = true;
            dgTaskList.AllowPaging = true;
            dgTaskList.PageSize = PAGE_SIZE;
            _presenter.GetContentSubmissionCount(pendingStatusID);

            dgTaskList.VirtualItemCount = Convert.ToInt32(GetContentSubmissionCount.Rows[0][0]);
            dgTaskList.DataSource = GetContentSubmissionSelect;
            dgTaskList.CurrentPageIndex = pageIndex;
            dgTaskList.DataBind();
        }
        else
        {
            dgTaskList.Visible = false;
            lblNoContent.Visible = true;
        }
    }

//handle the page index changed
    protected void dgTaskList_PageIndexChanged(object sender, DataGridPageChangedEventArgs e)
    {
        LoadContent(e.NewPageIndex);
    }

SQL Stored Procedure
We need to have two query where one to get the number of records and the other one is to get the actual result it self
To get the query/actual result

CREATE PROCEDURE uspContentSubmissionSelect
(
	@statusID int = NULL,
	@PageIndex int,
	@PageSize int
)
AS
	SET NOCOUNT ON;
SELECT
	o.Id, o.ContentSubmission_id, o.AppointmentId,
	o.Title, o.StatusName
FROM
	(
		SELECT
			r.ID, r.contentSubmission_id, r.AppointmentId,
			r.Title, s.StatusName,
			ROW_NUMBER() OVER (ORDER BY r.ID DESC) as RowNumber
		FROM
			MyInternet.ContentSubmissionRef r
		INNER JOIN
			MyInternet.Status s
		ON
			s.Id = r.StatusID
		AND
			((@StatusID IS NULL) OR (s.ID = @statusID))
	) o
WHERE
	o.RowNumber BETWEEN (@PageIndex * @PageSize + 1) AND ((@PageIndex * @PageSize) + @PageSize)
ORDER BY RowNumber
GO


To get the record count

CREATE PROCEDURE [dbo].[uspContentSubmissionCount]
(
	@statusID int = NULL
)
AS
	SET NOCOUNT ON;

		SELECT
			COUNT(*) AS TotalRow
		FROM
			MyInternet.ContentSubmissionRef r
		INNER JOIN
			MyInternet.Status s
		ON
			s.ID = r.StatusID
		AND
			((@StatusID IS NULL) OR (s.ID = @statusID))

How to find a query under a particular stored procedure in SQL Server

I’ve got a question this morning about how to find a particular query in a huge list of stored procedure. It’s not that hard, what you need to do is to use SYS object and sys.procedures basically contains all the stored procedure under the active database that you are using. This is the query that you can use to find a keyword product in any stored procedure

SELECT ROUTINE_NAME, ROUTINE_DEFINITION
    FROM INFORMATION_SCHEMA.ROUTINES
    WHERE ROUTINE_DEFINITION LIKE '%product%'
    AND ROUTINE_TYPE='PROCEDURE'

And the query below is used to find the stored procedure name that match with what you are looking for

SELECT *
FROM sys.procedures where OBJECT_DEFINITION(object_id) LIKE '%product%'

UPDATE:
How to find all the triggers on your Database

SELECT tbl1.[name] TableName, tbl0.[name] TriggerName,
CASE
WHEN tbl1.deltrig = tbl0.id  THEN 'OnDelete'
WHEN tbl1.instrig = tbl0.id THEN 'OnInsert'
WHEN tbl1.updtrig = tbl0.id THEN 'OnUpdate'
END 'Operation Type', tbl1.*,tbl0.*
FROM sysobjects tbl0 JOIN sysobjects tbl1 ON tbl0.parent_obj = tbl1.[id] WHERE tbl0.xtype='TR'

Divide by zero error occured in SQL Server

I tried to create an average in sql server by dividing two figures. Once I got the error of “Divide by zero error occured”, this is caused by dividing the figure by null value, to handle the error we can use “NULLIF”

DECLARE @ThisMonthAvg decimal(8,2)
SET @ThisMonthAvg = @ThisMonthPlayers / NULLIF(@ThisMonthEvents, 0)

DECLARE @LastMonthAvg decimal(8,2)
SET @LastMonthAvg = @LastMonthPlayers / NULLIF(@LastMonthEvents, 0)

DECLARE @ThisYearAvg decimal(8,2)
SET @ThisYearAvg = @ThisYearPlayers / NULLIF(@ThisYearEvents, 0)

DECLARE @LastYearAvg decimal(8,2)
SET @LastYearAvg = @LastYearPlayers / NULLIF(@LastYearEvents, 0)

Page 3 of 4

Powered by WordPress & Theme by Anders Norén