SQL Flashcards

1
Q

Difference between ON clause and Where clause in joins

A

Difference between ON clause and Where clause in joins

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

PIVOT

A
  • -https://www.youtube.com/watch?v=h3BtudZehuo
  • -PIVOT sql server operator that is used to turn unique values from one column into multiple columns in the output, there by effectively rotating a table
  • -for PIVOT to work, we need to have only the columns that we need to group by and aggregate this is achieved using temp, CTE or Derived tables
select * from (
select 
FORMAT(MonthStartDate, 'yyyy-MM') as DateInfo,--Non-Pivoted column from the source table - it is going to be included in the grouping for the pivot
TotalExpense,ExpenseType
--,ExpenseCategory -- this is additional grouping along with the date 
from MonthlyExpenseTracker
MET left join ExpenseType ET on MET.ExpenseTypeID=ET.ExpenseTypeID
left join ExpenseCategory EC on EC.ExpenseCategoryID=ET.ExpenseCategoryID
) as SourceTable -- this should have only the columns that we need in PIVOT ; we are using derived table here
PIVOT
(
sum(TotalExpense)
for ExpenseType in (
Restaurant
,Trips
,Travel
,Rent
,Internet
,Electricity
,[Education Loan]
,Groceries
,Others
,AtWork
,Shopping
,[Splitwise settlement]
,[Entrance Tickets]
,Entertainment
,Fuel
,Parking
,Medicine
,Electronics
,Furniture
,Insurance
,[Mobile bill]
,[Car Loan Payment]
,Gym
,Savings
,Retirement
,[God Prayer]
,[Future Generation]
,[Future Trips Savings]
,[Pocket Money]
,[Salary]
,[Hair Cut]
,Donations)
)
AS PIVOTTABLE -- alias name for pivot
order by DateInfo

–select * from ExpenseType

–select * from MonthlyExpenseTracker

  • -using MAX of a value will give the same values
  • -if we do not want to have aggregate function as sum,count; we could use MAX or MIN; just to pivot the values in the table

select [Maternal-Fetal Medicine],[Oral Surgery & Maxillofacial Surgery] from (
select DD.DimDiv_UPIR_DepartmentName as Division,M.LongMeasureName as Measure
,M.MeasureName –including additional column to the grouping to reduce the show the actual values for the measure
from odsDivMeas DM
left join DimDivision DD on DD.DimDivID_SK=DM.DivID
left join DimMeasure M on DM.MeasID=M.DimMeasureID_SK
where DM.DivID in (4,7) and DM.ActiveFlag=1)
as SourceTable
Pivot
(
MAX(Measure)
for Division in ([Maternal-Fetal Medicine],[Oral Surgery & Maxillofacial Surgery])
)
as PivotTable
order by [Maternal-Fetal Medicine],[Oral Surgery & Maxillofacial Surgery]

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Replace function in SQL

A

Replace “T” with “M”:

SELECT REPLACE(‘SQL Tutorial’, ‘T’, ‘M’);

The REPLACE() function replaces all occurrences of a substring within a string, with a new substring.

Note: The search is case-insensitive.

Tip: Also look at the STUFF() function.

Syntax
REPLACE(string, old_string, new_string)
Parameter Values
Parameter Description
string Required. The original string
old_string Required. The string to be replaced
new_string Required. The new replacement string

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

CAST(expression AS datatype(length))

A

The CAST() function converts a value (of any type) into a specified datatype.

Tip: Also look at the CONVERT() function.

Syntax
CAST(expression AS datatype(length))
Parameter Values
Value Description
expression Required. The value to convert
datatype Required. The datatype to convert expression to. Can be one of the following: bigint, int, smallint, tinyint, bit, decimal, numeric, money, smallmoney, float, real, datetime, smalldatetime, char, varchar, text, nchar, nvarchar, ntext, binary, varbinary, or image
(length) Optional. The length of the resulting data type (for char, varchar, nchar, nvarchar, binary and varbinary)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

CAST vs CONVERT

A

In this article, we will be exploring the CAST and CONVERT functions to understand whether there are any significant differences worth knowing when we want to data from one type to another.

Since the CAST and CONVERT can be used interchangeably in most situations, you may wonder if one function is better than the other.

Let’s read further. We will see whether there really is a difference between these two functions in this post.

The examples you’ll find in this lesson are based on the Microsoft SQL Server Management Studio and the AdventureWorks2012 database. You can get started using these free tools using my Guide Getting Started Using SQL Server.

Are Cast and Convert Different?
The CAST and CONVERT functions are both used to convert data from one data type to another, and it is no coincidence they share the same entry in MSDN.

Here is an example using both functions in the same statement:

SELECT CAST ('10' as int) * 20,
       CONVERT (int, '10') * 20
In both cases we’re converting from the text value ’10’ to its integer representation.

Hopefully this example jogs your memory regarding the CAST and CONVERT functions. If not, then read my blog Data Type Conversion Functions to know all the details.

Similarities with CAST and CONVERT
In many ways CAST and CONVERT are similar. Both are used to convert data from one type to another. Thought their syntax is different, both functions are able to convert values from one formation to another.

Anything you can do with CAST you can do with CONVERT. If you’re wondering whether there is a difference in performance in performance, according to Nakul Vachhrajani’s post, there isn’t. In fact, Nakul show that CAST is really implemented internally via CONVERT!

Differences between CAST and CONVERT
CAST is part of the ANSI-SQL specification; whereas, CONVERT is not. In fact, CONVERT is SQL implementation specific.

CONVERT differences lie in that it accepts an optional style parameter which is used for formatting.

For example, when converting a DateTime datatype to Varchar, you can specify the resulting date’s format, such as YYYY/MM/DD or MM/DD/YYYY.

SELECT CONVERT(VARCHAR,GETDATE(),101) as MMDDYYYY,
CONVERT(VARCHAR,GETDATE(),111) as YYYYMMDD
The numbers shown in red are the style formatter. There are many style formats you can use. The complete list is here.

Should I use CAST or Convert?
Unless you have some specific formatting requirements you’re trying to address during the conversion, I would stick with using the CAST function. There are several reason I can think of:

CAST is ANSI-SQL compliant; therefore, more apt to be used in other database implementation.
There is no performance penalty using CAST.
I think CAST is easier to read, and since it is part of the ANSI specification, your non-SQLServer DBA think so too!

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Getting columns for a select from objects

A

select the columns and drag and drop into the query window, it will pull up all the columns

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

using try catch for dropping temp table instead of objectID() verification

A

BEGIN TRY Drop table #Conditions end try begin catch end catch

You can include multiple tables in a DROP TABLE statement.

This will drop all that exist and raise an error for any that don’t.

If you don’t want those errors reported back you would need to use try..catch.

BEGIN TRY
      DROP TABLE #Scores1,
                 #Scores2,
                 #Scores3,
                 #Scores4,
                 #Scores5,
                 #Scores6,
                 #Scores7,
                 #Scores8
END TRY
BEGIN CATCH

END CATCH

i think try-catch will drop the temp tables but ObjectID will run a query against the tempdb, this might be performance hit but not sure

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Returning Muliple tables from stored procedure

A

create procedure ProcedureName
as
select * from table1
select * from table2

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Fetch rows in sql

A

in this tutorial, you will learn how to use the SQL Server OFFSET FETCH clauses to limit the number of rows returned by a query.
https://www.sqlservertutorial.net/sql-server-basics/sql-server-offset-fetch/

The OFFSET and FETCH clauses are the options of the ORDER BY clause. They allow you to limit the number of rows to be returned by a query.

The following illustrates the syntax of the OFFSET and FETCH clauses:

1
2
3
ORDER BY column_list [ASC |DESC]
OFFSET offset_row_count {ROW | ROWS}
FETCH {FIRST | NEXT} fetch_row_count {ROW | ROWS} ONLY
In this syntax:

The OFFSET clause specifies the number of rows to skip before starting to return rows from the query. The offset_row_count can be a constant, variable, or parameter that is greater or equal to zero.
The FETCH clause specifies the number of rows to return after the OFFSET clause has been processed. The offset_row_count can a constant, variable or scalar that is greater or equal to one.
The OFFSET clause is mandatory while the FETCH clause is optional. Also, the FIRST and NEXT are synonyms respectively so you can use them interchangeably. Similarly, you can use the FIRST and NEXT interchangeably.

The following illustrates the OFFSET and FETCH clauses:

SQL Server OFFSET FETCH

Note that you must use the OFFSET and FETCH clauses with the ORDER BY clause. Otherwise, you will get an error.

The OFFSET and FETCH clauses are preferable for implementing the query paging solution than the TOP clause.

The OFFSET and FETCH clauses have been available since SQL Server 2012 (11.x) and later and Azure SQL Database.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

To skip the first 10 products and return the rest, you use the OFFSET clause as shown in the following statement:

A
SELECT
    product_name,
    list_price
FROM
    production.products
ORDER BY
    list_price,
    product_name 
OFFSET 10 ROWS;
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

To skip the first 10 products and select the next 10 products, you use both OFFSET and FETCH clauses as follows:

A
SELECT
    product_name,
    list_price
FROM
    production.products
ORDER BY
    list_price,
    product_name 
OFFSET 10 ROWS 
FETCH NEXT 10 ROWS ONLY;
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

To get the top 10 most expensive products you use both OFFSET and FETCH clauses:

A
SELECT
    product_name,
    list_price
FROM
    production.products
ORDER BY
    list_price DESC,
    product_name 
OFFSET 0 ROWS 
FETCH FIRST 10 ROWS ONLY;

In this example, the ORDER BY clause sorts the products by their list prices in descending order. Then, the OFFSET clause skips zero row and the FETCH clause fetches the first 10 products from the list.

In this tutorial, you have learned how to use the SQL ServerOFFSET FETCH clauses the limit the number of rows returned by a query.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

isnumeric(Order_value)

A

select * from stgHbA1C where
isnumeric(Order_value)=0

to check if the data in this field is numeric value =0 means non-numeric and =1 means numeric

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Passing parameters to the query and running open query

A

DECLARE @HistStartDate as varchar(12);
SET @HistStartDate = ‘01/01/2019’;

SET @Qry = ‘ select ser.prov_id,ser.prov_name, p.pat_name, p.pat_mrn_id, p.pat_id, e.pat_enc_csn_id, e.contact_date,
TO_CHAR(rslt.ord_num_value) as ord_num_value,TO_CHAR(rslt.ord_value) as ord_value
from pat_enc e join patient p on p.pat_id = e.pat_id join order_results rslt on rslt.pat_enc_csn_id = e.pat_enc_csn_id and rslt.component_id in (801002,802097,801046,805282,700194,700185,700046) left join clarity_ser ser on ser.prov_id = e.visit_prov_id where e.appt_prc_id in (‘’'’20790’’’’,’’'’823’’’’,’’'’826’’’’,’’'’800’’’’,’’'’804’’’’,’’'’801’’’’,’’'’20120’’’’,’’'’20121’’’’,’’'’1743’’’’) and e.department_id in (20001010,20010010) and e.appt_status_c = 2 and e.contact_date >= to_date(‘’’’’ + @HistStartDate + ‘’’’’,’’'’DD/MM/YYYY’’’’) order by e.contact_date desc ‘;
SET @OPENQUERY=’select * from OPENQUERY(PERIOPRPT,’’’
+ @Qry + ‘’’)’

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

executing open query from SQL to oracle

A

DECLARE @OPENQUERY VARCHAR(max);
DECLARE @Qry VARCHAR(max);

SET @Qry = ‘ select ser.prov_id,ser.prov_name, p.pat_name, p.pat_mrn_id, p.pat_id, e.pat_enc_csn_id,
e.contact_date,TO_CHAR(rslt.ord_num_value) as ord_num_value,TO_CHAR(rslt.ord_value) as ord_value
from pat_enc e join patient p on p.pat_id = e.pat_id join order_results rslt on rslt.pat_enc_csn_id = e.pat_enc_csn_id and rslt.component_id in (801002,802097,801046,805282,700194,700185,700046) left join clarity_ser ser on ser.prov_id = e.visit_prov_id where e.appt_prc_id in (‘’'’20790’’’’,’’'’823’’’’,’’'’826’’’’,’’'’800’’’’,’’'’804’’’’,’’'’801’’’’,’’'’20120’’’’,’’'’20121’’’’,’’'’1743’’’’) and e.department_id in (20001010,20010010) and e.appt_status_c = 2 and e.contact_date >= to_date(‘’'’01-07-2019’’’’,’’'’DD-MM-YYYY’’’’) and e.contact_date <= to_date(‘’'’31-12-2019’’’’,’’'’DD-MM-YYYY’’’’) order by e.contact_date desc ‘;
SET @OPENQUERY=’select * from OPENQUERY(PERIOPRPT,’’’
+ @Qry + ‘’’)’

		   EXEC (@OPENQUERY);
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Debug; conditional debugging

A

https://www.youtube.com/watch?v=AlRNA8pmfIk

Step over;
Step Into
Step Out
Show Next statement
Run to cursor
Locals Window
Watch Window
Call Stack
Immediate Window
Conditional Debugging/breakpoint
17
Q

Get column names of tempdb

A

SELECT *
FROM tempdb.sys.columns
WHERE object_id = Object_id(‘tempdb..#ASQResults’);

18
Q

Insert into table by turning off the identity

A

SET IDENTITY_INSERT [dbo].[stgASQ] ON
GO
INSERT [dbo].[stgASQ] ([stgASQ_ID], [VISIT_PROV_ID], [VISIT_PROV_NAME], [PAT_NAME], [MRN], [EncounterID], [Contact_Date], [ASQSuccess], [DateKey], [DateCreated], [DateModified], [DimDivID_SK], [DimProvID_SK], [Pat_ID], [Birth_date], [DEPARTMENT_ID], [DEPARTMENT_NAME], [Prov_Type], [appt_prc_id], [appt_prc_name], [appt_time], [Enc_Close_Date], [Site], [AgeInDays], [Age_In_Months], [ASQ_8-16_months], [ASQ_17-23_months], [ASQ_24-35_months], [ASQ_24-35_Result], [ASQ_36-47_months], [ASQ_48-59_months], [ASQ_48-59_Result], [ASQ_54_months], [ASQ_60-65_months], [DueForASQ], [ASQ], [ASQ_date], [Numerator], [Denominator]) VALUES (1, N’100713’, N’MORGAN, DARICE A.’, N’DANIELS,AIDEN’, N’11732701’, CAST(550208435 AS Numeric(18, 0)), CAST(N’2020-03-05’ AS Date), N’1’, N’20200305’, CAST(N’2020-07-14T17:18:41.653’ AS DateTime), CAST(N’2020-07-14T17:18:41.717’ AS DateTime), 38, 3477, N’Z1964554’, CAST(N’2016-11-15T00:00:00.000’ AS DateTime), N’20001410’, N’CCM SBHC ROCKDALE ACADEMY’, N’Nurse Practitioner’, N’23545’, N’ROC * WCC’, CAST(N’2020-03-05T10:30:00.000’ AS DateTime), CAST(N’2020-03-05’ AS Date), N’Rockdale’, N’1206’, N’39’, NULL, N’2018-05-03’, NULL, NULL, NULL, NULL, NULL, NULL, NULL, N’1’, N’Pass’, CAST(N’2020-03-05T11:04:00.000’ AS DateTime), N’1’, N’1’)
GO

SET IDENTITY_INSERT [dbo].[stgASQ] OFF
GO

19
Q

Rank vs Dense Rank vs Row Number

A
SELECT name,company, power,
RANK() OVER(ORDER BY power DESC) AS PowerRank
FROM Cars
Power Rank
800     1
800     1
500     3
400     4

DENSE_RANK Function
SELECT name,company, power,
RANK() OVER(PARTITION BY company ORDER BY power DESC) AS PowerRank
FROM Cars

Power Rank
800     1
800     1
500     2
400     3

ROW_NUMBER Function
SELECT name,company, power,
ROW_NUMBER() OVER(ORDER BY power DESC) AS RowRank
FROM Cars

Power Rank
800     1
800     2
500     3
400     4
https://codingsight.com/similarities-and-differences-among-rank-dense_rank-and-row_number-functions/
20
Q

To update a variable with a delimiter from the select of the dataset

A

DECLARE @recipients VARCHAR(MAX);
select @recipients =
COALESCE(@recipients +’;’,’’)+EmailAddress
from NonProviderEmailList where DimDivID_SK=@DivisionID and Active=1

21
Q

for inclusion or exclusion of portion of data from a whole data
(@ProviderID=0 or review.OPPE_Provider_Review_ID is null)

A

declare @ProviderID int=1

  • -@ProviderID = 1 - get providers that have not submitted
  • -@ProviderID = 0 - get all providers for this division

SELECT @recipients = COALESCE(@recipients + ‘;’, ‘’) + Email
from DimProvider providerTable – base table is all providers
left join (select * from UniqueProviderSubmitted where RowNum=1) review on providerTable.Provider_ID = review.ProviderID
inner join #FOE FOETable on FOETable.DimProvID_SK=providerTable.DimProvID_SK
LEFT OUTER JOIN [Datamart_OPPE].[dbo].[Users] u ON u.UserNetworkID = providerTable.UserNetworkID
where providerTable.Active_Status <>’Inactive’ and providerTable.ActiveTo is null– get provider review table
and providerTable.HasZeroMeasures=’False’
and (providerTable.AssignmentID=@DivisionID or providerTable.OPAssignmentID=@DivisionID)
and (@ProviderID=0 or review.OPPE_Provider_Review_ID is null)

when providerID=0 it means 0=0 and we want to see all the records without any filter

when providerID=1 it means then the reviewid=null is satisfied and we will be able to see only that subset of data

—same logic applies
@FilterValue varchar(50) =’’

where (@FilterValue=1 or @FilterValue =’’)

@FilterValue varchar(50) =null
where (@FilterValue=1 or @FilterValue =NULL)

22
Q

To make sql parameters optional

A

—same logic applies
@FilterValue varchar(50) =’’

where (@FilterValue=1 or @FilterValue =’’)

@FilterValue varchar(50) =null
where (@FilterValue=1 or @FilterValue =NULL)

23
Q

Sparse columns

A

https: //www.youtube.com/watch?v=q8gAPDHcpKw
https: //www.youtube.com/watch?v=0pR9ofa7VY8

used when there are columns in the table that have more than 60% of null values, this saves the space on the database server

if there are no null values then it takes up more space

create table products (
Prod_Num  int,
price decimal (7,2),
width float SPARSE NULL,
color char(5) SPARSE NULL,
Details XML COLUMN_SET FOR ALL_SPARSE_COLUMN
)

column set groups all the sparse column in a table with XML nodes

select * from products will not show the sparse columns but will show the details column with xml nodes

select Prod_Num, price, color, Details from products will show all the columns

24
Q

sp_spaceused tableName

A

to check the table used space in the data column

25
Q

Get only first few columns in a table dynamically

A

SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = ‘tbl_product’ AND ORDINAL_POSITION = ‘3’

	select column_name,ordinal_position
  from information_schema.columns
 where table_schema ='dbo'
   and table_name ='tbl_product'
   and ordinal_position <= 2

DECLARE @column varchar(100)
DECLARE @SQL varchar(100)

SELECT @column = COALESCE(@column + ', ', '') + 
   CAST(column_name AS varchar(100))
from information_schema.columns
where table_name='tbl_product'
and ordinal_position in (1,2,3) 

print @column

SET @SQL=’SELECT’+’ ‘+ @column+’ ‘+ ‘FROM’+’ ‘+’tbl_product’
PRINT @SQL
EXEC(@SQL)

26
Q

loading data into temp table

A
create table #tempdb1
(
ID int primary key identity(1,1),
productID int,
ProductName varchar(100)
)

insert into #tempdb1 (productID,ProductName)
EXEC(@SQL)

or

insert into #tempdb1
EXEC(@SQL)

DECLARE @column varchar(100)
DECLARE @SQL varchar(100)

SELECT @column = COALESCE(@column + ‘, ‘, ‘’) +
CAST(column_name AS varchar(100))
from information_schema.columns
where table_name=’tbl_product’
and ordinal_position <=(select count (*) from tbl_department where departmentId in (1,2))

print @column

SET @SQL=’SELECT’+’ ‘+ @column+’ ‘+ ‘FROM’+’ ‘+’tbl_product’
PRINT @SQL

insert into #tempdb1 (productID,ProductName)
EXEC(@SQL)

27
Q

EAV - Entity Attribute Value

A

we want to to have a single row there can be one value for a given attribute/column

CREATE TABLE APPCONFIG
(
attribute NVARCHAR(256) NOT NULL PRIMARY KEY
,Value SQL_VARIANT NULL
)

Advantage:
you do not need to chagne the table definition for adding a new column, we could just insert a new row
Disadvantage:
we do not have type checking for a specific data point
, we need to check manually
IF (SQL_VARIANT_PROPERTY (Value, ‘BaseType’)<>’DATETIME’) THEN we have to reject the row

we could use trigger here as well

28
Q

SQL_VARIANT type of variable

A

DECLARE @x SQL_VARIANT = 258
SELECT @X, SQL_VARIANT_PROPERTY(@X,’BaseType’)

output : 258 , int

SET @X =’Scott’

SELECT @X, SQL_VARIANT_PROPERTY(@X,’BaseType’)
output: Scott and varchar

29
Q

There are a few diferences between VARCHAR(1-8000) and VARCHAR(MAX).

A

when you store data to a VARCHAR(N) column, the values are physically stored in the same way. But when you store it to a VARCHAR(MAX) column, behind the screen the data is handled as a TEXT value. So there is some additional processing needed when dealing with a VARCHAR(MAX) value. (only if the size exceeds 8000)

VARCHAR(MAX) or NVARCHAR(MAX) is considered as a ‘large value type’. Large value types are usually stored ‘out of row’. It means that the data row will have a pointer to another location where the ‘large value’ is stored. By default sql server will try to accomodate the value ‘in row’ but if it could not, it will store the large values ‘out of row’. When values are stored ‘out of row’ there will be slight processing overhead in reading the information. Here is a good reference: http://msdn2.microsoft.com/en-us/library/ms189087.aspx

I guess you cannot index a VARCHAR(MAX)/NVARCHAR(MAX) column.

coming back to your question:

I dont think it is bad to use VARCHAR(MAX) is bad. If you are storing smaller piecs of data in a VARCHAR(MAX) column, it will be treated as normal. If you dont want to index the column, then you can definitely go with VARCHAR(MAX) option.

But most people do not advise that. First of all, by having a VARCHAR(MAX) will confuse some one who looks at the data later on. For example, if you want to store a comment of 100 characters or address of 80 characters, why should you go for VARCHAR(MAX)? If you use Address VARCHAR(MAX), comments VARCHAR(MAX), Name VARCHAR(MAX), some one trying to read or write data on a later date will be confused. They will not know what is the expected size of the data and they will be compelled to use LARGE VALUE types always.

Again, these are not rules but conventions.

The storage is only part of the story here. There is also the internals story of the way MAX fields are handled. Since they span pages, the internal code must stream. While it might be nice to have it treat single page versus multiple page differently (single pointer on a single page; multiple on multiple), there is a perf hit for making the decision “does it span”, so the engine streams on all MAX fields. The perf hit is small, so it is not a huge deal in all but the largest applications, but if you know your data can fit in a varchar(n) field it is better to use a large n value than use max. Max is a safety net, but if you don’t need it, don’t put it up.

100 characters stored in an nvarchar(MAX) field will be stored no different to 100 characters in an nvarchar(100) field - the data will be stored inline and you will not have the overhead of reading and writing data ‘out of row’. So no worries there.

If the size is greater than 4000 the data would be stored ‘out of row’ automatically, which is what you would want. So no worries there either.

However…

You cannot create an index on an nvarchar(MAX) column. You can use full-text indexing, but you cannot create an index on the column to improve query performance. For me, this seals the deal…it is a definite disadvantage to always use nvarchar(MAX).

30
Q
use varchar(8000) instead of 
varchar(max) or nvarchar(max)
A
use varchar(8000) instead of 
varchar(max) or nvarchar(max)
31
Q

Natural Keys
Surrogate keys
Primary key

A

Natural keys - these are natural in the data like username, user email address
Surrogate keys - these are additional keys that are added to the tables to uniquely identify the rows; these are usually private and has no outside world / business significance

if you are struggling to find a good natural key, you could find a surrogate key

if we have userName in the table and surrogate key like userid, we could still index userName column but we use userid to connect between tables

Primary key - we want only one primary key for table
it is unique
not changing
not null

Surrogate key is a type of Primary key
Natural key is a type of Primary Key

Generally, a Surrogate Key is a sequential unique number generated by SQL Server or the database itself. The purpose of a Surrogate Key is to act as the Primary Key. There is a slight difference between a Surrogate Key and a Primary Key. Ideally, every row has both a Primary Key and a Surrogate Key. The Primary Key identifies the unique row in the database while the Surrogate Key identifies a unique entity in the model.

32
Q

composite key/Composite primary key

A

Primary keys are special types of constraint that uniquely identify all rows in a table. Usually, we choose a single column as the primary key in our table to maintain data integrity. However, if necessary, we can also choose several columns as a primary key to prevent duplications.

Often, composite keys are useful when we’re working with relation tables, which are tables that connect two or more tables.

Let’s look at an example of a composite primary key.

In a simple hotel reservation system, suppose that each person only stays for one day in the hotel. We wouldn’t want to have a room reserved by two guests on the same night. By creating a composite key that contains the date and room number, we can ensure that a room is not double reserved for the same day.

CREATE TABLE Reservation (
RoomNumber INT NOT NULL,
DateOfStay DATE NOT NULL,
Guest VARCHAR(50),
CONSTRAINT PK_Reservation_2 PRIMARY KEY (RoomNumber, DateOfStay)
)

Creating a composite key in SQL Server is as easy as creating a primary key that consists of one column, and we can do that using SSMS or T-SQL.

There might be cases when we don’t think that there is a single column that can serve as our table’s primary key. Besides, we might want to avoid adding a surrogate key (such as an integer auto-increment field) to the system. If so, we may consider using a composite key made of two or more columns.

33
Q

IDENT_CURRENT ,@@IDENTITY ,SCOPE_IDENTITY

i think it is better to use SCOPE_IDENTITY as it is based on current session and current scope; this avoids any id if there are triggers for the insert command

A

https: //www.c-sharpcorner.com/UploadFile/rohatash/identity-and-scope_identity-in-sql-server-2012/
https: //docs.microsoft.com/en-us/sql/t-sql/functions/ident-current-transact-sql?view=sql-server-ver15

IDENT_CURRENT returns the last identity value generated for a specific table in any session and any scope.
@@IDENTITY returns the last identity value generated for any table in the current session, across all scopes.
SCOPE_IDENTITY returns the last identity value generated for any table in the current session and the current scope.

Alter TRIGGER InsertTriger  
ON [UserDetail]  
after INSERT AS  
   BEGIN  
   INSERT [UserTable] VALUES ('Lyon')  
   END  
   go  
INSERT INTO [dbo].[UserDetail]  
           ([UserName]  
           ,[CompanyName]  
           ,[Salary])  
     VALUES('Ashish','NTPC','15000')  
SELECT SCOPE_IDENTITY() AS SCOPEIDENTITYOUTPUT  
SELECT @@IDENTITY AS IDENTITYOUTPUT  
GO 

The preceding output shows SCOPE_IDENTITY returned the last identity value in the same scope. @@IDENTITY returned the last identity value inserted to UserDetail by the trigger.

When inserting a row in a stored procedure, always use SCOPE_IDENTITY() if you want to get the ID of the row that was just inserted. A common error is to use @@IDENTITY, which returns the most recently created identity for your current connection, not necessarily the identity for the recently added row in a table. You could have a situation where there is a trigger that inserts a new record in a Logs Table, for example, when your Stored Procedure or INSERT SQL Statement inserts a record in the Orders Table. If you use @@IDENTITY to retrieve the identity of the new order, you will actually get the identity of the record added into the Log Table and not the Orders Table, which will create a nasty bug in your data access layer. To avoid the potential problems associated with someone adding a trigger later on, always use SCOPE_IDENTITY() to return the identity of the recently added row in your INSERT SQL Statement or Stored Procedure.
​Behold this example from SQL Server Books online.

SCOPE_IDENTITY
4
/SCOPE_IDENTITY returned the last identity value in the same scope. This was the insert on table TZ./
@@IDENTITY
115
/@@IDENTITY returned the last identity value inserted to TY by the trigger. This fired because of an earlier insert on TZ./​

34
Q

Create a “Last Modified” Column in SQL Server with trigger

A

CREATE TABLE dbo.Books (
BookId int IDENTITY(1,1) NOT NULL PRIMARY KEY,
BookName nvarchar(1000) NOT NULL,
CreateDate datetime DEFAULT CURRENT_TIMESTAMP,
ModifiedDate datetime DEFAULT CURRENT_TIMESTAMP
);

CREATE TRIGGER trg_Books_UpdateModifiedDate
ON dbo.Books
AFTER UPDATE
AS
UPDATE dbo.Books
SET ModifiedDate = CURRENT_TIMESTAMP
WHERE BookId IN (SELECT DISTINCT BookId FROM inserted);

https: //database.guide/create-a-last-modified-column-in-sql-server/
https: //www.codeproject.com/Articles/21937/Create-a-Modified-On-Column-in-SQL-Server

35
Q

sql triggers for update

A

https: //stackoverflow.com/questions/48159627/trigger-for-update-table-after-update-records-in-another-table
https: //www.sqlshack.com/triggers-in-sql-server/

https://stackoverflow.com/questions/460316/
are-database-triggers-evil#:~:text=
They%20are%
20often%20wrong.,application
%20may%20be%20affecting%20things.
36
Q

Using the inserted and deleted Tables in INSTEAD OF Triggers

A

https://docs.microsoft.com/en-us/sql/relational-databases/triggers/use-the-inserted-and-deleted-tables?view=sql-server-ver15

37
Q

Filestream
FileDirectory
FileTable

A

select * from sys.filegroups

use Datamart_OPPE
ALTER DATABASE Datamart_OPPE ADD FILEGROUP OPPE_FILESTREAM_grp CONTAINS FILESTREAM
GO

USE master
Go
EXEC sp_configure ‘show advanced options’
Go

USE master
Go
EXEC sp_configure
Go

EXEC sp_configure filestream_access_level, 2
GO
RECONFIGURE WITH OVERRIDE
GO

  SELECT sdf.name AS [FileName],
size/128 AS [Size_in_MB],
fg.name AS [File_Group_Name]
FROM sys.database_files sdf
INNER JOIN
sys.filegroups fg
ON sdf.data_space_id=fg.data_space_id
SELECT DISTINCT   obj.[name],   obj.[type],  fg.[name]
FROM sys.indexes ind
INNER JOIN sys.filegroups fg
ON ind.data_space_id = fg.data_space_id
INNER JOIN sys.tables obj
ON ind.[object_id] = obj.[object_id]
WHERE obj.type = 'U'-- — User Tables
GO

ALTER DATABASE Datamart_OPPE ADD FILE ( NAME = N’Datamart_OPPE_FS_test’, FILENAME = N’J:\cealld01ms_data3\FileStream\Datamart_OPPE\demofiles’ ) TO FILEGROUP OPPE_FILESTREAM_grp
GO

ALTER DATABASE Datamart_OPPE
SET FILESTREAM ( NON_TRANSACTED_ACCESS = FULL, DIRECTORY_NAME = N’OPPE_FileStream_Directory’ )
USE master
GO
SELECT [value],[value_in_use],description FROM [sys].[configurations] WHERE name= ‘filestream access level’

SELECT DB_NAME(database_id) as DatabaseName, non_transacted_access, non_transacted_access_desc
FROM sys.database_filestream_options
where DB_NAME(database_id)=’SQLFileTable’;
GO

ALTER DATABASE Datamart_OPPE
REMOVE FILEGROUP OPPE_FILESTREAM_grp ;

use Datamart_OPPE
ALTER DATABASE Datamart_OPPE Modify FILEGROUP OPPE_FILESTREAM_grp CONTAINS FILESTREAM
GO

CREATE DATABASE SQLFileTable
ON PRIMARY
(
    NAME = SQLFileTable_data,
    FILENAME = 'C:\sqlshack\FileTable\SQLFileTable.mdf'
),
FILEGROUP FileStreamFG CONTAINS FILESTREAM
(
    NAME = SQLFileTable,
    FILENAME = 'C:\sqlshack\FileTable\FileTable_Container' 
)
LOG ON
(
    NAME = SQLFileTable_Log,
    FILENAME = 'C:\sqlshack\FileTable\SQLFileTable_Log.ldf'
)
WITH FILESTREAM
(
    NON_TRANSACTED_ACCESS = FULL,
    DIRECTORY_NAME = N'FileTableContainer'
);
GO

SELECT DB_NAME(database_id) as DatabaseName, non_transacted_access, non_transacted_access_desc
FROM sys.database_filestream_options
where DB_NAME(database_id)=’Datamart_OPPE’;
GO

1
2
3
Select DB_NAME ( database_id) as DatabaseName, directory_name
FROM sys.database_filestream_options
where DB_NAME(database_id)=’Datamart_OPPE’;

CREATE TABLE OPPE_Documents_FileTable
AS FILETABLE
WITH
(
FileTable_Directory = ‘OPPE_FileStream_Directory’,
FileTable_Collate_Filename = database_default
);

USE [Datamart_OPPE]
GO

/** Object: Table [dbo].[mDimMeasureDocuments] Script Date: 6/2/2021 3:12:50 PM **/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[mDimMeasureDocuments](
	[MeasureDocumentID] [int] IDENTITY(1,1) NOT NULL,
	[DimMeasureID_SK] [int] NOT NULL,
	DocumentFileName [varchar](8000) NULL,
  [DateCreated] [datetime] NULL,
	[DateModified] [datetime] NULL,
	[ActiveFlag] [bit] NULL,
	[LastUpdatedBy] [int] NULL,
PRIMARY KEY CLUSTERED 
(
	[MeasureDocumentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[mDimMeasureDocuments] ADD CONSTRAINT [DF_mDimMeasureDocuments_DateCreated] DEFAULT (getdate()) FOR [DateCreated]
GO

ALTER TABLE [dbo].[mDimMeasureDocuments] ADD CONSTRAINT [DF_mDimMeasureDocuments_ActiveFlag] DEFAULT (‘1’) FOR [ActiveFlag]
GO

ALTER TABLE [dbo].[mDimMeasureDocuments] WITH CHECK ADD CONSTRAINT [FK_mDimMeasureDocuments_DimMeasure] FOREIGN KEY([DimMeasureID_SK])
REFERENCES [dbo].[DimMeasure] ([DimMeasureID_SK])
GO

ALTER TABLE [dbo].[mDimMeasureDocuments] CHECK CONSTRAINT [FK_mDimMeasureDocuments_DimMeasure]
GO

ALTER TABLE [dbo].[mDimMeasureDocuments] WITH CHECK ADD CONSTRAINT [FK_mDimMeasureDocuments_Users] FOREIGN KEY([LastUpdatedBy])
REFERENCES [dbo].[Users] ([UserID])
GO

ALTER TABLE [dbo].[mDimMeasureDocuments] CHECK CONSTRAINT [FK_mDimMeasureDocuments_Users]
GO

ALTER TABLE [dbo].[mDimMeasureDocuments] ADD Document varbinary FILESTREAM NULL