Datetime2 => bigint (od. Float, Real, …)

Quelle/n:

https://siderite.dev/blog/how-to-translate-t-sql-datetime2-to.html

DATEDIFF_BIG

Beim SQL war DATEDIFF schon länger bekannt und üblich. Leider konnten Zeiträume viel zu schnell größer sein, als dies man z.B. in Sekunden erfassen konnte.
Microsoft bietet einige neue Prozeduren, die im Namen zusätzlich ein „…_BIG“. Einsetze ich das DATEDIFF_BIG speziell beim LOGGING.
Aber auch ein DATEDIFF_BIG kann zu einer Fehlermeldung führen bzw. zu einem Überlauf wenn man z.B. die Nanosekunden zwischen Heute und dem 01.01.0001 berechnet…
Mir reichen zur Genauigkeit die Mikrosekunden aus und dann kann das Ergebnis in einer Variablen „bigint“ speichern.

Quelle/n:
https://learn.microsoft.com/de-de/sql/t-sql/functions/datediff-big-transact-sql?view=sql-server-ver16

Benutzung von Oracle (Tabellen, Prozeduren)

Befehle Anlage von Tabellen, Prozeduren etc.:

https://docs.oracle.com/cd/E18283_01/server.112/e17120/tables003.htm#i1106335

https://stackoverflow.com/questions/1799128/oracle-if-table-exists

https://docs.oracle.com/cd/E10405_01/appdev.120/e10379/ss_oracle_compared.htm

https://asktom.oracle.com/pls/apex/f?p=100:11:::::P11_QUESTION_ID:9541246000346968042

Unterschiede der Datentypen bzw. das Mapping von Datentypen:
https://learn.microsoft.com/en-us/sql/relational-databases/replication/non-sql/data-type-mapping-for-oracle-publishers

https://www.mssqltips.com/sqlservertip/2944/comparing-sql-server-and-oracle-datatypes/

Die Neuanlage von Oracle Datenbanken sind nicht so einfach wie MS SQL Server….

Ganze Tabellen einer Datenbank sichern als einzelner Datensatz

Ganze Tabellen einer Datenbank sichern
Es werden in diesem Beispiel in einer Schleife eine Tabelle einer Staging-Datenbank in einem einzigem Feld eines Satzes in der [BackupsTabelle] in einer anderen Datenbank [BackupDB] gesichert.

Es wird dabei auch T-SQL Code bereitgestellt, um diese komprimierten und gesicherten Daten, ohne Aufwand lesbar zu machen.

Durch diese Form der Sicherungen, können mglw. komplette ETL-Strecken, zu erneut eingespielt werden.

Ganze Tabellen einer Datenbank sichern.docx

Limits: Ein Feld mit dem Typ NVARCHAR(MAX) kann nicht mehr als 2 GByte  enthalten

SQL Formatter (leider nur bis SSMS 2019)

Beim Lesen von T-SQL im SSMS fehlt immer wieder eine Formatierungs-Hilfe.
Praktisch fand ich:
Quelle/n (des gleichen Entwicklers):
https://github.com/TaoK/PoorMansTSqlFormatter
Ist GitHub, aber nur schwierig die richtige *.msi zu finden
http://architectshack.com/PoorMansTSqlFormatter.ashx#Download_15
Hier muss man die „Extension for CURRENT VERSION of SSMS….“ suchen und kann die PoorMansTSqlFormatterSSMSPackage.Setup.1.6.16.msi laden und installieren.

Ggf. ist noch das .NET Framework 2.0 nötig:
Download .NET 2.0 SP1 (x64) from Official Microsoft Download Center

Das SSMS muss ggf. neu gestartet werden und dann ist im Menü „Tools“ der Punkt „Format T-SQL Code“

Benutzung:
Den SQL Code, den man in einer Query hat, kann man dann über den o.g. Punkt den Code neu formatiert anzeigen lassen. Typisch ist das nötig, wenn man komplexe Stored Procedure in einer einzigen Zeile findet.

Sollte man eine Fehlermeldung sehen:
---------------------------
Microsoft SQL Server Management Studio
---------------------------
The 'FormatterPackage' package did not load correctly.

The problem may have been caused by a configuration change or by the installation of another extension.
You can get more information by examining the file
‚C:\Users\frank.odenbreit\AppData\Roaming\Microsoft\AppEnv\14.0\ActivityLog.xml‘.

Restarting Visual Studio could help resolve this issue.

Continue to show this error message?
—————————
Ja Nein
—————————

Lösung:
https://github.com/TaoK/PoorMansTSqlFormatter/issues/187
EINFACH DEN DIALOG MIT „NO“ bzw. „NEIN“ BESTÄTIGEN!!!!
Siehe d. o.g. Link:

Don't bother reading all that text - I messed up the installer during the split at the start of the week.
The problem will have been temporary (as long as you say "No" in the error dialog, the extension loads fine on next SSMS restart and forever after), but still, almost 300 downloads of the bad installer... :(
Fixed installer is live, downloadable at http://architectshack.com/PoorMansTSqlFormatter.ashx
Sorry about the inconvenience.

In einzelnen Fällen war das Menü deaktiviert („grau“). In dem Fall hat mir dieser Link geholfen die Konfiguration des SSMS anzupassen („ssms.exe.config“):

https://stackoverflow.com/questions/63313632/poor-mans-t-sql-formatting-add-in-format-t-sql-code-option-disabled-in-sql-ser

 

Datenbank shrinken, aber die Dateien werden nicht kleiner?

Prinzipiell sollte es möglich sein eine Datenbank oder einzelne Dateien, z.B. das LOG zu verkleinern. Aber diese werden niemals kleiner, als die „Inital Size“.

Wenn es jedoch immer noch nicht funktioniert, kann es an vorhandenen Indizes liegen, die auch sehr stark fragmentiert sein können.

Gute „vorbereitete Lösung“ habe ich gefunden bei:

https://blog.pmd-media.com/2009/10/08/howto-verkleinern-einer-microsoft-sql-server-datenbank/

--Erst alle Indizes neu aufbauen
DECLARE @TableName varchar(255)
DECLARE TableCursor CURSOR FOR
   SELECT DISTINCT QUOTENAME(TABLE_SCHEMA)+'.'+QUOTENAME(table_name)
   FROM information_schema.tables
   WHERE table_type = 'base table'
   order by 1 asc
OPEN TableCursor
FETCH NEXT FROM TableCursor INTO @TableName
WHILE @@FETCH_STATUS = 0
BEGIN
   print @TableName+'....'
   DBCC DBREINDEX(@TableName,' ',90)
   FETCH NEXT FROM TableCursor INTO @TableName
END
CLOSE TableCursor
DEALLOCATE TableCursor
print 'FERTIG'

--Und nachher wirklich shrinken:
go
dbcc shrinkdatabase    (0, 10, NOTRUNCATE)
--Erster Parameter := Aktuelle DB
--Zweiter Parameter := Wieviel Prozent soll "leer" bleiben
go
dbcc shrinkdatabase    (0, 10, TRUNCATEONLY)
--dto.
GO

/*
--Quelle: https://qastack.com.de/server/31554/how-to-check-progress-of-dbcc-shrinkfile
--In einem anderem Fenster könnte man sehen wie weit der Shrink-Prozess ist:
select  T.text, R.Status, R.Command, DatabaseName = db_name(R.database_id)
        , R.cpu_time, R.total_elapsed_time, R.percent_complete as [ca.percent]
from    sys.dm_exec_requests R
        cross apply sys.dm_exec_sql_text(R.sql_handle) T
*/

SSMS verbraucht CPU und reagiert nicht mehr alle paar Minuten…

Problem: Das SSMS (SQL Server Management Studio) hängt alle paar Minuten – Auch ein Neustart des SSMS bringt nichts.
Nebeninformation: CPU vom SSMS wird 15-25% und das RAM vom SSMS mehrere GB!

 

Ursache: Eine T-SQL Query ist syntaktisch defekt und das SSMS „wild“ zu werden. Es scheint mit einem Zusammenhang mit dem IntelliSense zu haben.

Lösung: Korrektur des T-SQL Code und ein paar Minuten geduldig sein, CPU verringert sich schneller und das RAM normalisiert sich etwas später!

Ähnliche Feststellungen:
https://superuser.com/questions/1195570/sql-server-management-studio-cpu-and-ram-usage-keeps-increasing-for-no-reason

Dynamisches SQL – Beispiel „Anzahl von Sätzen allen Tabellen“

Gelegentlich möchte man sich T-SQL generieren lassen und dann auch noch starten zu lassen. Als Beispiel ist eine Kontrolle, ob wirklich alle Tabellen „truncated“ wurde…. Manchmal kommt noch eine Tabelle hinzu und schon wird vergessen dass auch diese neue Tabelle auch geleert sein sollte. Das Beispiel soll nur zeigen, wie es möglich ist – der Befehl STRING_AGG funktioniert erst ab SQL Server 2016 (Vorher wurde XML in dem SQL eingebaut):

DECLARE @Schema nvarchar(64) = 'dbo'
DECLARE @SQL nvarchar(max)
DECLARE @ParmDefinition nvarchar(max) = '@CountOUT int OUTPUT'
DECLARE @Count bigint
Select @SQL='SELECT @CountOUT = '+STRING_AGG('(Select count(1) from ['+[schemas].[name]+'].['+[tables].[name]+'])','+')
from sys.tables tables left outer join sys.schemas schemas on schemas.schema_id=tables.schema_id 
where [tables].[type]='U' 
and [schemas].[name] like @Schema
EXEC sp_executesql @SQL, @ParmDefinition, @CountOUT=@Count OUT
Select @Count as TotalRows

Hinweis: Der Befehlt STRING_AGG() darf jedoch maximal 8000 Zeichen produzieren – daher wird dies im Zweifel nicht benutzt werden kann!

Link/s:
https://docs.microsoft.com/de-de/sql/relational-databases/system-stored-procedures/sp-executesql-transact-sql?view=sql-server-2017

SQL Server: Welcher Port wird vom SQL Server genutzt?

Es ist zwar möglich die alle Ports festzustellen
netstat -ano
Aber das macht eine zu lange Liste…
Kurzer Test ob der Standard Port 1433 festgelegt ist:
netstat -ano | findstr 1433
Aber wenn das nichts bringt, dann den SQL Server selber fragen:

SELECT DISTINCT 
    local_tcp_port 
FROM sys.dm_exec_connections 
WHERE local_tcp_port IS NOT NULL 

T-SQL Settings: LANGUAGE, Dateformat und DATEFIRST

Immer wieder wäre es schön kurzeitig andere Einstellungen zu nutzten. Speziell damit T-SQL Batches sehr unabhängig arbeiten können:

--Save the old / usual settings:
DECLARE @DATEFIRST int = @@DATEFIRST
DECLARE @LANGUAGE nvarchar(100) = @@LANGUAGE
DECLARE @DATEFORMAT nvarchar(100) = (
   select	s.date_format 
   from	sys.dm_exec_sessions s 
   where	s.session_id = @@SPID
   )
--Set new temporary Settings:
SET DATEFIRST 7;
SET DATEFORMAT mdy;
SET LANGUAGE US_ENGLISH;
…
…
--Restore the saved settings:
SET LANGUAGE @language;  /*Germany: "Deutsch" */
SET DATEFIRST @DATEFIRST;  /*Germany: "dmy" */
SET DATEFORMAT @DATEFORMAT;  /*Germany: "1" */

ACHTUNG: Variablen sind alle verloren nach jedem „GO“ – auch wenn ein GO in einem Kommentar seht ist das meist verloren!
Wie auch immer, solche Einstellungen gelten ohnehin nur in aktuellen Session.

T-SQL: Fehlende Indizes…

Häufig scheinen Abfragen überraschend langsam sein, oder immer langsam werden…. Als Tunings-Maßnahme lohnen sich meist als erster Versuch Indizes in der Datenbank. Lediglich sind bestimmte Rechte für der u. g. TSQL-Code notwendig


-- Missing Index Script
-- Original Author: Pinal Dave (C) 2011
-- verändert von Frank Odenbreit 2011/2013/2016

/*
Es werden zwar die 50 wichtigsten Indizes geholt und diese nachher sortiert nach ihrem Namen
(Ähnlichkeiten sollte man erkennen können, ggf. anpassen bzw. aus kommentieren)
*/


Select *
from (
SELECT TOP 50
	dm_mid.database_id AS DatabaseID,
	dm_migs.user_seeks as user_seeks,
	dm_migs.avg_user_impact as avg_user_impact, 
	dm_migs.avg_user_impact * (dm_migs.user_seeks+dm_migs.user_scans) AS Avg_Estimated_Impact,
	dm_migs.last_user_seek AS Last_User_Seek,	object_name(dm_mid.object_id) AS [TableName],
	--*,

	'CREATE NONCLUSTERED INDEX [ndx' + object_name(dm_mid.object_id) + '__'
	+ REPLACE(REPLACE(REPLACE(ISNULL(dm_mid.equality_columns,''),', ','_'),'[',''),']','') +
	CASE
	WHEN dm_mid.equality_columns IS NOT NULL AND dm_mid.inequality_columns IS NOT NULL THEN '_'
	ELSE ''
	END
	+ REPLACE(REPLACE(REPLACE(ISNULL(dm_mid.inequality_columns,''),', ','_'),'[',''),']','')
	+ ']'
	
	+ ' ON ' + dm_mid.statement		+ ' (' + ISNULL (dm_mid.equality_columns,'')
	+ CASE WHEN dm_mid.equality_columns IS NOT NULL AND dm_mid.inequality_columns IS NOT NULL THEN ',' ELSE
	'' END
	+ ISNULL (dm_mid.inequality_columns, '')
	+ ')'
	
	+ ISNULL (' INCLUDE (' + dm_mid.included_columns + ')', '') 
	+ '  WITH (pad_index=OFF,Fillfactor=90,ignore_dup_key=OFF,allow_row_locks=ON,allow_page_locks=ON,DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]'
	
	AS Create_Statement
	
FROM sys.dm_db_missing_index_groups dm_mig
	INNER JOIN sys.dm_db_missing_index_group_stats dm_migs ON dm_migs.group_handle = dm_mig.index_group_handle
	INNER JOIN sys.dm_db_missing_index_details dm_mid ON dm_mig.index_handle = dm_mid.index_handle
WHERE dm_mid.database_ID = DB_ID()
ORDER BY Avg_Estimated_Impact DESC 
) as t
order by Create_Statement asc

SQL: Rekursive Abfragen

 


/*
Hierarchie von Firmen
---------------------
Egal wo man steht, erst den obersten ParentAccount suchen 
und von dort aus alle Kinder feststellen
--http://www.bidn.com/blogs/KeithHyer/bidn-blog/2293/hierarchy-with-recursive-cte-and-a-little-borrowed-sorting-trickery
*/


/*Muster MSCRM BusinessUnit:*/
--Select Name, * from Team order by 1

With hBU(Name, BusinessUnitId, ParentBusinessUnitIdName, ParentBusinessUnitId, Levl, sortBU)
As (
	/*Anker*/
	Select Name, BusinessUnitId, ParentBusinessUnitIdName, ParentBusinessUnitId , 0 Levl , CONVERT( VARchar(MAX) , ( BusinessUnit.Name  ) ) as sortBU
	From BusinessUnit 
	Where ParentBusinessUnitId IS NULL /*and Name = 'dkacrm'*/

	union all

	/*Recursion*/
	Select BusinessUnit.Name, BusinessUnit.BusinessUnitId, BusinessUnit.ParentBusinessUnitIdName, BusinessUnit.ParentBusinessUnitId , Levl + 1 as Levl, CONVERT( VARchar(MAX) , ( SortBU + BusinessUnit.Name  ) ) as sortBU
	From BusinessUnit 
		inner join hBU on hBU.BusinessUnitId = BusinessUnit.ParentBusinessUnitId
	Where BusinessUnit.ParentBusinessUnitId IS NOT NULL 

) 
Select coalesce(replicate(char(124)+'    ',Levl-1)+replicate(char(43)+'    ',Levl-Levl+1) ,'') + hBU.Name , *
from hBU
order by sortBU
	



/*Muster MSCRM Account:
  Wobei die Felder CustomerTypeCode und ImportSequenceNumber nur Firmen/Kunden-spezifisch sind
*/
With hAcc(Name, Accountid, ParentAccountIdName, ParentAccountid, CustomerTypeCode, ImportSequenceNumber, Levl, SortAcc)
As (
	/*Anker*/
	Select Name, AccountId, ParentAccountIdName, ParentAccountId, CustomerTypeCode, ImportSequenceNumber, 0 Levl, CONVERT( Varchar(MAX) , Name ) as SortAcc
	From Account 
	Where 1=1
		and CustomerTypeCode in (200002  /*Debitoren*/, 200000  /*Filialen*/)
		and ParentAccountId IS NULL

	union all
	
	/*Recursion in CTE*/
	Select Account.Name, Account.AccountId, Account.ParentAccountIdName, Account.ParentAccountId, Account.CustomerTypeCode, Account.ImportSequenceNumber, Levl + 1, CONVERT( Varchar(MAX) , SortAcc + Account.Name ) as SortAcc
	From Account 
		inner join hAcc on hAcc.Accountid=Account.ParentAccountId
	Where 1=1
		and Account.CustomerTypeCode in (200002  /*Debitoren*/, 200000  /*Filialen*/)
		and Account.ParentAccountId IS NOT NULL
)
Select coalesce(replicate(char(124)+'    ',Levl-1)+replicate(char(43)+'    ',Levl-Levl+1) ,'') + Name as Name, 
	CustomerTypeCode, StringMap.Value as CustomerTypeCodeReadable,
	/*Case when CustomerTypeCode = 200000 then 'Filiale' when CustomerTypeCode = 200002 Then 'Debitor' else '???' end CustomerTypeCodeReadable,*/
	AccountId, ParentAccountId, ParentAccountIdName, CustomerTypeCode, ImportSequenceNumber, Levl
From hAcc
	left outer join StringMap on StringMap.AttributeName = 'CustomerTypeCode' and StringMap.LangId = 1031 and StringMap.AttributeValue = hAcc.CustomerTypeCode
Order by SortAcc








/*Muster SLX Account:*/
Declare @Ankerid char(12);
SET @Ankerid = 'A6UNMA000DQO'; --z.B. Firma Muster GmbH & Co. KG  (ist ein Kind weil es ein Parent hat)
--SET @Ankerid = 'A6UJ9A00050W'; --z.B. Muster Holding AG (ist OberAccount)

--Von hier aus den Obervater finden:
DECLARE @ToplevelAccountid char(12);
WITH hAcc(Account, Accountid, ParentAccountid, Levl)
AS (
	--Anker:	
	Select Account, Accountid, Parentid AccountParentid, 0 Levl 
	from Account 
	where Accountid=@Ankerid
	
	union all
	
	--Rekursion in CTE:
	Select Account.Account Account, Account.Accountid Accountid, Account.Parentid ParentAccountid, Levl + 1
	from Account 
		inner join hAcc on hAcc.ParentAccountid = Account.Accountid
	--where Parentid IS NOT NULL
)
--Select Account, Accountid, ParentAccountid, Levl from hAcc where ParentAccountid IS NULL
Select @ToplevelAccountid = Accountid from hAcc where ParentAccountid IS NULL; 
--Print @ToplevelAccountid

--Von hier aus alle Kinder:
WITH hAcc(Account, Accountid, ParentAccount, ParentAccountid, Levl, SortAcc)
AS (
	--Anker (also alle Sätze, die keine Kinder mehr haben):	
	Select Account, Accountid, cast(NULL AS Varchar(128)) ParentAccount, Parentid ParentAccountid, 0 Levl
	,CONVERT( VARchar(MAX) , Account ) as SortAcc
	from Account 
	where Parentid IS NULL
	and Accountid=@ToplevelAccountid
	
	union all
	
	--Rekursion in CTE:
	Select Account.Account Account, Account.Accountid Accountid, hAcc.Account ParentAccount, Account.Parentid ParentAccountid,	Levl + 1
	, CONVERT( VARchar(MAX) , ( SortAcc + Account.Account  ) ) as SortAcc
	from Account 
		inner join hAcc on hAcc.Accountid=Account.Parentid
	where Parentid IS NOT NULL
)
Select 
Account Account,
coalesce(replicate(char(124)+'    ',Levl-1)+replicate(char(43)+'    ',Levl-Levl+1) ,'') Leveling, 
'' FirstChar, 
Accountid, ParentAccount, ParentAccountid, Levl, 
(Case when @Ankerid = Accountid Then 1 else 0 end) Markierung
,SortAcc
--,Row_Number() Over(order by SortAcc asc) RowNum 
from hAcc 
order by SortAcc 


/*
--Beispiel:
Select parentid, Account, Accountid from Account where Accountid='A6UJ9A000F01'
Select parentid, Account, Accountid from Account where Accountid='A6UJ9A00050W'
*/

Select * from account
Select * from gc_account_ext
Select * from ACC_CORPORATE

Select a.ACCOUNT, a.ACCOUNTID, ac.ACCOUNTID, ac.ACC_PARENTID 
from account a
inner join ACC_CORPORATE ac on a.ACCOUNTID=ac.ACCOUNTID
	

;WITH LoopIT( PARENT, CHILD )
AS (
	--Anker (also alle Sätze, die keine Kinder mehr haben):	
	Select ac.ACC_PARENTID, ac.ACCOUNTID
	From ACC_CORPORATE ac 
	where ac.ACC_PARENTID NOT IN (Select ac2.ACCOUNTID From ACC_CORPORATE ac2) 

	union all
	
	--Rekursion in CTE:
	Select r.ACC_PARENTID, r.ACCOUNTID
	From LoopIT r
		inner join ACC_CORPORATE acr on r.ACCOUNTID = acr.ACC_PARENTID
)
Select PARENT, CHILD FROM LoopIT

Hinweis: Standardmäßig sind jedoch nur 100 Rekursionen erlaubt und werden mit einem Fehler abgerochen. Lösung: Ganz an das Ende des T-SQL Code, also auch hinter „WHERE“-Bedingung/en und „Order BY“:

OPTION (MAXRECURSION 32767)

 

Speicher Situation eines SQL Servers


/**************************************************************
Wieviel Platz ist auf dem Filesystem des SQL Servers
und wie wird der RAM benutzt?

***************************************************************/

DECLARE @DB varchar(255)
SET @DB =   --'FOD_Test_DB'
--Hier ist bewusst ein Fehler eingebaut, damit die DB korrekt festgelegt ist



/*
Physikalische Größe und freien Speicher in den Datenbanken
*/
exec ('use '+@DB+';
select 
      name 
    , filename 
    , convert(decimal(12,2),round(a.size/128.000,2)) as FileSizeMB 
    , convert(decimal(12,2),round(fileproperty(a.name,''SpaceUsed'')/128.000,2)) as SpaceUsedMB 
    , convert(decimal(12,2),round((a.size-fileproperty(a.name,''SpaceUsed''))/128.000,2)) as FreeSpaceMB 
from dbo.sysfiles a;'+
'use '+'tempdb'+';
select 
      name 
    , filename 
    , convert(decimal(12,2),round(a.size/128.000,2)) as FileSizeMB 
    , convert(decimal(12,2),round(fileproperty(a.name,''SpaceUsed'')/128.000,2)) as SpaceUsedMB 
    , convert(decimal(12,2),round((a.size-fileproperty(a.name,''SpaceUsed''))/128.000,2)) as FreeSpaceMB 
from dbo.sysfiles a')



/*
Freier Speicher im Filesystem des SQL-Servers: 
*/
exec xp_fixeddrives



/*
Aufteilung des Arbeitspeicher des Systems
*/
/*
Select * from sys.dm_os_memory_pools
Select * from sys.dm_os_memory_allocations
Select * from sys.dm_os_memory_clerks 
Select * from sys.dm_os_memory_objects 
Select * from sys.dm_os_memory_nodes 
--Ab SQL Server 2008 möglich: 
Select cast(round(total_physical_memory_kb/1024.0/1024.0,2) as decimal(10,2)) PhysicalRAM_GB
	,cast(round(available_physical_memory_kb/1024.0/1024.0,2) as decimal(10,2)) AvailableRAM_GB
	,*
from sys.dm_os_sys_memory
*/

SQL: Binäre Darstellung wandeln in Integer (’0101′ => 5)

/*
Binary to Decimal


Zwei Teile:
1) Stored Function
2) CTE, ohne Function!

--MUSTER:
--select sysdba.fod_Int2Binary(5242881)
select sysdba.fod_Binary2Int('00000000010100000000000000000001', 17, 32)
*/


IF EXISTS (select name, * from sysobjects where name = 'fod_Binary2Int' and Type = 'FN') Drop function fod_Binary2Int
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		
-- Create date:	<2008-01-22>
-- Description:	
-- =============================================
CREATE FUNCTION fod_Binary2Int (@Folge as char(32), @Von as Int, @Bis as Int) 
RETURNS Int
AS
BEGIN
	-- Declare the return variable here
	DECLARE @Result int
	DECLARE @Zeichen char(1)
	Declare @i int
	
	SET @Result = 0
	SET @i = @Von
	WHILE (@i <= @Bis)
	Begin
		SET @Result = @Result * 2
		SET @Zeichen = Substring(@Folge, @i, 1)
		IF @Zeichen = '1'
			SET @Result = @Result + 1
		SET @i = @i + 1
	End

	-- Return the result of the function
	RETURN @Result
END
GO



------------------------------------------------


/*
Binary to Decimal
Link: http://improve.dk/converting-between-base-2-10-and-16-in-t-sql/  ( robert matthew cook )
*/
;with table_64_bit as
	(
	select CONVERT(varchar(64), '0') as bit_check, CONVERT(bigint, 0) as decimal_value
	union all
	select CONVERT(varchar(64), '1%'), CONVERT(bigint, 1)
	union all
	select CONVERT(varchar(64), REPLACE(SPACE(LEN(bit_check)-1), ' ', '_') + '1%'), CONVERT(bigint, POWER(CONVERT(bigint, 2), LEN(bit_check)-1)) from table_64_bit where LEN(bit_check) between 2 and 63
	)
select
	from_binary, sum(decimal_value) as to_decimal
from table_64_bit
join (select '11101011001011010101111010000' as from_binary) as fake_table on reverse(from_binary) like bit_check
group by
	from_binary;



SQL: Integer wandeln in Binäre Darstellung (5=>’0101′)

/*
Integer => Binär 
Zwei Varianten:
1) Stored Function
2) T-SQL, ohne Function

--MUSTER:
select sysdba.fod_Int2Binary(5242881)
--select sysdba.fod_Binary2Int('00000000010100000000000000000001', 17, 32)
*/


IF EXISTS (select name, * from sysobjects where name = 'fod_Int2Binary' and Type = 'FN') Drop function fod_Int2Binary
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		
-- Create date:	<2008-01-22>
-- Description:	
-- =============================================
CREATE FUNCTION fod_Int2Binary (@Zahl as Int)
--, @PreNulls as char(1)) 
RETURNS char(32)
AS
BEGIN
	-- Declare the return variable here
	DECLARE @Result char(32)
	Declare @Rest int
	Declare @Anteil int
	
	SET @Result = ''
	SET @Anteil = @Zahl
	WHILE (@Anteil > 0)
	Begin
		Set @Rest = @Anteil % 2
		SET @Anteil = @Anteil / 2
		Set @Result = ltrim(str(@Rest)) + @Result
	End
	
	--If (@PreNulls = 'T')
		Set @Result = right('0000000000' + '0000000000' + '0000000000' + '00' + rtrim(ltrim(@Result)) , 32)

	-- Return the result of the function
	RETURN @Result
END
GO




---------------------------------------------------------



Declare @i as bigint = 5242881    --> 00000000010100000000000000000001
Select 
        CASE WHEN CONVERT(VARCHAR(16), @i & Cast(2147483648 as bigint) ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i & Cast(1073741824 as bigint) ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i & 536870912 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i & 268435456 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i & 134217728 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i & 67108864 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i & 33554432 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i & 16777216 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i & 8388608 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i & 4194304 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i & 2097152 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i & 1048576 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i & 524288 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i & 262144 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i & 131072 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i & 65536 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i & 32768 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i & 16384 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i &  8192 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i &  4096 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i &  2048 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i &  1024 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i &   512 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i &   256 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i &   128 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i &    64 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i &    32 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i &    16 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i &     8 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i &     4 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i &     2 ) > 0 THEN '1' ELSE '0'   END +
        CASE WHEN CONVERT(VARCHAR(16), @i &     1 ) > 0 THEN '1' ELSE '0'   END

MS SQL: SQL-Code von Views, Trigger Prozeduren und Funktionen darstellen

/*

Darstellen von SQL Code von Views. Trigger, Prozeduren und Funktionen

*/
Select s.name, m.definition 
from sys.sql_modules m inner join sys.views s ON s.object_id = m.object_id 
where 1=1


Select s.name, m.definition 
from sys.sql_modules m inner join sys.triggers s ON s.object_id = m.object_id 
where 1=1


Select s.name, m.definition 
from sys.sql_modules m inner join sys.procedures s ON s.object_id = m.object_id 
where 1=1
order by 1


Select s.name, m.definition 
from sys.sql_modules m inner join sys.objects s on s.object_id = m.object_id and s.Type='FN'
where 1=1
order by 1

Problem 1: Nicht immer sind die CRLF verblieben

Problem 2: Code ist möglw. länger als 4000/8000 Zeichen

Problem 3: Code ist möglw. verschlüsselt

MS SQL: Wie weit ist das Datenbank Backup? Wie viele Prozent sind durch?

Falls ein Backup sehr viel Zeit braucht, wäre es schön, wenn man einmal feststellen kann, wie weit das Backup ist:

/*
Wenn ein Backup länger lauft, kann man feststellen wie weit das Backup ist.

Ggf. hilft diese Recht zum Lesen dieses Code auch anderen geben:
GRANT VIEW SERVER STATE TO [sqluser_loginname]
*/

Select Session_id asSPID, r.database_id, r.command, a.text as Query, start_time, percent_complete,
DATEADD(Second, estimated_completion_time/1000, GetDate()) as estimated_completion_time
From sys.dm_exec_requests r cross Apply sys.dm_exec_sql_text(r.sql_handle) a
Where r.command in ('Backup Database', 'Restore Database', 'Backup Log')

Übrigens: Ich habe die Dauer von Backups gebraucht, als Probleme beim Zugriff auf ein RAID System einmal bestand…

Funktion: Jahr, Monat und Tag als „Datetime“…

 

IF EXISTS (select name, * from sysobjects where name = 'fod_YMD2Datetime' and Type = 'FN') Drop function fod_YMD2Datetime
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION fod_YMD2Datetime(@Year int, @Month int, @Day int)
RETURNS datetime
AS
-- =============================================
-- Author: FOd	
-- Create date:	<2009-01-30>
-- Description:	Aus Jahr, Monat und Tag ein Datetime liefern
-- =============================================
BEGIN

  DECLARE @d datetime;

  SET @d = dateadd(year,(@Year - 1753),'1/1/1753');
  SET @d = dateadd(month,@Month - 1,@d);
  SET @d = dateadd(day, @Day - 1, @d);
  RETURN @d
END
go

--Select dbo.gc_YMD2Datetime(2009, 1, 30)