MS-Office-Forum
Google
   

Zurück   MS-Office-Forum > Microsoft Access & Datenbanken > SQL
Registrieren Forum Hilfe Alle Foren als gelesen markieren

Banner und Co.

Antworten
Ads Der Renner, 11 Entwicklertools für Access, Tipps & Trick und offene Datenbanken zum einzigartigen Preis.
Themen-Optionen Ansicht
Alt 28.11.2016, 09:32   #1
stefaktiv
MOF User
MOF User
Standard T-SQL : MSSQL 2014 - SQL Server 2016 Express - In-Memory-OLTP nutzen (Timestamp)

Zuerst einmal der Hinweis, dass noch ein Präfix für den neuen MSSQL-Server 2016 fehlt.

Seit dem SP1 des SQL Server 2016 steht die OLTP-Technik ja auch in der Express-Variante zur Verfügung. Ich würde auch liebend gerne die Tabellen entsprechend in den Speicher verlegen, habe aber das Problem, dass es keine Timestamp-Datenfelder mehr gibt. Das ist dahingehend blöd, weil ich bei einem Teil der Abfragen auf die Information zurückgreife, welcher Datensatz zuletzt geändert wurde.

Gibt es zum Timestamp zukünftig denn keinen Ersatz?
stefaktiv ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Alt 27.01.2017, 20:26   #2
stefaktiv
Threadstarter Threadstarter
MOF User
MOF User
Standard

Mmm - weiß dazu niemand eine rechte Antwort? Hat jemand die neue Technik schon einmal ausprobiert?
stefaktiv ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Alt 27.01.2017, 22:10   #3
Markus Chemnitz
MOF Koryphäe
MOF Koryphäe
Standard

es wird wohl das Format 'timestamp' nicht mehr unterstützt in den 'In Memory' Tabellen, genauso wie das 'Text' Format. Sehr zu meinem Bedauern. Es hindert Dich aber nicht daran anstatt des timesampts ein Getdate() da rein zu schreiben - das sollte wohl auch funktionieren.
Ich habe mit den 'In Memory' Tabellen auch mal rumexperimentiert. Der Aufwand eine alte Tabelle da hin zu bekommen ist schon exorbitant. Zudem werden einige Formate wie timestamp, text oder berechnete Spalten gar nicht akzeptiert. Zudem komme ich nie in den Entwurfsmodus einer 'In Memory Tabelle'. Dazu muss ich immer SQL bemühen. Ich weiß auch nicht so recht ob das der große Performance Bringer ist. Vielleicht ist es geschickter die alte Datenbank auf SSD Devices auszulagern.

__________________

MarkB

Vom Leben nichts zu erwarten, ist das Geheimnis aller echten Heiterkeit!

Geändert von Markus Chemnitz (27.01.2017 um 22:20 Uhr).
Markus Chemnitz ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Alt 29.01.2017, 22:26   #4
stefaktiv
Threadstarter Threadstarter
MOF User
MOF User
Standard

Also bei einem Test konnte ich die Tabelle im SSMS schon im Entwurfmodus umstellen. Nur die Timestamp-Werte hat er eben nicht übernommen. Rein vom Test im SSMS war die Abfragegeschwindigkeit auch wirklich sehr viel schneller. Ich denke, dass es für meinen Anwendungsfall auf jeden Fall etwas bringen wird.

Mein Problem ist aber, dass ich auf diesen Werten Abfragen aufgesetzt habe. In einer Tabelle sind Personen gespeichert, in anderen Entitäten wie Adressen, Emailadressen und Telefonnummern. Als Verbindung gibt es noch pro Entitätsart eine Zwischentabelle, so dass eine Adresse für mehrere Personen vergeben werden kann. In vielen Berichten soll aber nur eine Adresse ausgegeben werden - und zwar immer diejenige, die als letzte aktuelle Adresse eingegeben oder geändert wurde.

Hierzu nutze ich dann den Timestamp-Wert. Natürlich könnte man auch ein Datumsfeld nutzen. Wichtig wäre aber, dass es keine doppelten Zeiten geben kann - es müsste also wohl bis zur Milisekunde exakt sein. Sonst bekommt man ein Problem, wenn automatisiert zwei Adressen hintereinander für die gleiche Person eingetragen werden.

Irgendwie müsste ich jetzt auch die Timestamp-Reihenfolge auf eine Ersatzspalte mit dem Datum und der genauen Zeit der letzten Änderung transferieren... nachdem der Timestamp kein echtes Datum ist, dürfte das aber schwierig sein.
stefaktiv ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Alt 30.01.2017, 14:00   #5
Markus Chemnitz
MOF Koryphäe
MOF Koryphäe
Standard

also ich habe mal gegoogelt, es ist im SQL Server nicht möglich aus einem timestamp Wert eine Datetime zu machen - definitiv. Ich habe mal selbst rumgespielt und habe aus den timstamp Spalten varchar (50) Spalten gemacht. Dnach konne ich bei einer Abfrage mit order by nach den Timestamp (varchar(50)) Werten sauber sortieren. Vielleicht ist das ein Ansatz. Zukünftig würde ich an Deiner Stelle aber mit Getdate() arbeiten. Damit befüllst Du eine datetime Spalte als Standardwert. Leider darfst Du dazu Deine Applikation komplett umstellen... :-(

__________________

MarkB

Vom Leben nichts zu erwarten, ist das Geheimnis aller echten Heiterkeit!
Markus Chemnitz ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Alt 31.01.2017, 12:27   #6
sonic8
MOF Profi
MOF Profi
Standard

Zitat: von Markus Chemnitz Beitrag anzeigen

also ich habe mal gegoogelt, es ist im SQL Server nicht möglich aus einem timestamp Wert eine Datetime zu machen - definitiv.

Das ist so, weil eine TSQL-Timestamp nichts mit Datum und Uhrzeit zu tun hat und damit auch nicht konform mit dem SQL-Standard ist.
Das ist auch der Grund, warum der TSQL-Timestamp-Datentyp auch "deprecated" ist und davon abgeraten wird, ihn weiterhin zu verwenden.

Ein SQL-Standard-Timestamp entspricht bei SQL-Server dem Datetime-Datentyp.

Der Ersatz für einen alten TSQL-Timestamp ist der Datentyp Rowversion.
sonic8 ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Alt 02.02.2017, 14:32   #7
Markus Chemnitz
MOF Koryphäe
MOF Koryphäe
Standard

SQL Server 2016: Wenn ich aber eine Speichertabelle anlege und als Datentyp 'rowversion' in einer Spalte angebe wird das beim Ausführen angefehlert, das timestamp - Formate in Speichertabellen nicht möglich sind. Das scheint mir auch keine Lösung zu sein.

__________________

MarkB

Vom Leben nichts zu erwarten, ist das Geheimnis aller echten Heiterkeit!
Markus Chemnitz ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Alt 03.07.2017, 21:41   #8
stefaktiv
Threadstarter Threadstarter
MOF User
MOF User
Standard

Zu dem Problem fehlt mir irgendwie immer noch eine Lösung. Ich stell mal die Beispielkonstellation vor. Dazu muss man erst mal drei Tabellen erstellen.

Eine Tabelle für die Personen:

Code:

CREATE TABLE [dbo].[Personen](
	[Pers_ID] [int] IDENTITY(1,1) NOT NULL,
	[Pers_Nachname] [nvarchar](100) NULL,
	[Pers_Geburtsname] [nvarchar](100) NULL,
	[Pers_Vorname] [nvarchar](100) NULL,
	[Pers_Vorname_Weitere] [nvarchar](100) NULL,
	[Pers_Geburtsdatum] [datetime] NULL,
	[Pers_Geburtsort] [nvarchar](100) NULL,
	[Pers_Geburtsland] [nvarchar](100) NULL,
	[Pers_Geschlecht] [nvarchar](50) NULL,
	[Pers_Anlagedatum] [datetime] NULL,
	[Pers_angelegt_durch] [nvarchar](100) NULL,
	[Pers_Letzte_Änderung] [datetime] NULL,
	[Pers_geändert_durch] [nvarchar](100) NULL,
	[Pers_Timestamp] [timestamp] NULL,
 CONSTRAINT [PK_Personen] PRIMARY KEY CLUSTERED 
(
	[Pers_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

Eine Tabelle für E-Mailadressen:

Code:

CREATE TABLE [dbo].[Emailadressen](
	[Email_ID] [int] IDENTITY(1,1) NOT NULL,
	[Email_Adresse] [nvarchar](255) NULL,
	[Email_Dienstlich] [bit] NOT NULL,
	[Email_Privat] [bit] NOT NULL,
	[Email_Aktuell] [bit] NOT NULL,
	[Email_Anlagedatum] [datetime] NULL,
	[Email_angelegt_durch] [nvarchar](100) NULL,
	[Email_Letzte_Änderung] [datetime] NULL,
	[Email_geändert_durch] [nvarchar](100) NULL,
	[Email_Timestamp] [timestamp] NULL,
 CONSTRAINT [PK_Emailadressen] PRIMARY KEY CLUSTERED 
(
	[Email_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

ALTER TABLE [dbo].[Emailadressen] ADD  CONSTRAINT [DF_Emailadressen_Email_Dienstlich]  DEFAULT ((0)) FOR [Email_Dienstlich]
GO

ALTER TABLE [dbo].[Emailadressen] ADD  CONSTRAINT [DF_Emailadressen_Email_Privat]  DEFAULT ((1)) FOR [Email_Privat]
GO

ALTER TABLE [dbo].[Emailadressen] ADD  CONSTRAINT [DF_Emailadressen_Email_Aktuell]  DEFAULT ((1)) FOR [Email_Aktuell]
GO

Zuletzt noch eine Tabelle zur Verknüpfung zwischen Person und E-Mailadresse.

Code:

CREATE TABLE [dbo].[PersEmail](
	[PersEmail_ID] [int] IDENTITY(1,1) NOT NULL,
	[Pers_ID] [int] NULL,
	[Email_ID] [int] NULL,
	[PersEmail_Quelle] [nvarchar](255) NULL,
	[PersEmail_Hinweistext] [nvarchar](255) NULL,
	[PersEmail_inaktuell] [bit] NOT NULL,
	[PersEmail_inaktuell_seit] [datetime] NULL,
	[PersEmail_Anlagedatum] [datetime] NULL,
	[PersEmail_angelegt_durch] [nvarchar](255) NULL,
	[PersEmail_Letzte_Änderung] [datetime] NULL,
	[PersEmail_geändert_durch] [nvarchar](255) NULL,
	[PersEmail_Timestamp] [timestamp] NULL,
 CONSTRAINT [PK_PersEmail] PRIMARY KEY CLUSTERED 
(
	[PersEmail_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[PersEmail] ADD  CONSTRAINT [DF_PersEmail_PersEmail_inaktuell]  DEFAULT ((0)) FOR [PersEmail_inaktuell]
GO

ALTER TABLE [dbo].[PersEmail]  WITH CHECK ADD  CONSTRAINT [FK_PersEmail_Emailadressen] FOREIGN KEY([Email_ID])
REFERENCES [dbo].[Emailadressen] ([Email_ID])
GO

ALTER TABLE [dbo].[PersEmail] CHECK CONSTRAINT [FK_PersEmail_Emailadressen]
GO

ALTER TABLE [dbo].[PersEmail]  WITH CHECK ADD  CONSTRAINT [FK_PersEmail_Personen] FOREIGN KEY([Pers_ID])
REFERENCES [dbo].[Personen] ([Pers_ID])
GO

ALTER TABLE [dbo].[PersEmail] CHECK CONSTRAINT [FK_PersEmail_Personen]
GO

Wenn die Frage kommen sollte, weshalb die Tabellen nicht direkt miteinander verbunden sind: jede E-Mailadresse kann mit mehreren Personen verknüpft sein und jede Person kann mit mehreren E-Mailadressen verknüpft sein. In der Datenbank ist jede Person und jede E-Mailadresse nur einmal vorhanden.

Dazu gibt es dann noch einen kleinen Trigger, der die Verknüpfung zwischen Person und E-Mailadresse auf inaktuell stellt, wenn die E-Mailadresse als inaktuell markiert wird.

Code:

CREATE TRIGGER [dbo].[tr_Emailadressen_After_Update]
ON [dbo].[Emailadressen] AFTER Update, Insert

AS

BEGIN


-- Prüfen, ob die Emailadresse auf inaktuell geschalten wurde
IF UPDATE(Email_aktuell)

   BEGIN

   SET NOCOUNT ON;

	UPDATE	dbo.PersEmail
   
	SET		PersEmail_inaktuell =	-1,
			PersEmail_inaktuell_seit = CONVERT(DATE, GETDATE()),
			PersEmail_Letzte_Änderung = CONVERT(DATE, GETDATE()),
			PersEmail_geändert_durch = 'Datenbanktrigger - Emailadresse inaktuell'
		
	FROM	inserted INNER JOIN dbo.PersEmail
			ON inserted.Email_ID = dbo.PersEmail.Email_ID 

	WHERE	PersEmail_inaktuell =	0 AND
			inserted.Email_aktuell = 0

	END



END



GO

ALTER TABLE [dbo].[Emailadressen] ENABLE TRIGGER [tr_Emailadressen_After_Update]
GO
stefaktiv ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Alt 03.07.2017, 21:53   #9
stefaktiv
Threadstarter Threadstarter
MOF User
MOF User
Standard

Hier wäre jetzt ein Beispielcode für eine meiner Abfragen, mit welcher ich die aktuellste E-Mailadresse der Person anzeigen lasse. Das ist immer dann relevant, wenn z.B. in einer Personenliste nur eine E-Mailadresse Platz hat.

Am aktuellsten definiere ich dabei die E-Mailadresse, deren Verknüpfung zur Person zuletzt geändert wurde.

Code:

SELECT		P.Pers_ID, Pers_Nachname, Pers_Vorname, Pers_Geburtsdatum, Pers_Geschlecht, Pers_Geburtsort,
			PE.PersEmail_ID, Email_Adresse

FROM		Personen P
			
			LEFT OUTER JOIN
			(SELECT * FROM dbo.PersEmail WHERE PersEmail_inaktuell = 0) AS PE ON PE.Pers_ID = P.Pers_ID 
			
			LEFT OUTER JOIN
			(SELECT * FROM dbo.Emailadressen WHERE Email_Aktuell = 1) AS email ON email.Email_ID = PE.Email_ID

WHERE		P.Pers_ID = @intID AND

			((PE.PersEmail_Timestamp IS NULL) OR
			(PE.PersEmail_Timestamp = (	SELECT		MAX(PersEmail_Timestamp) AS Expr1
										FROM		(SELECT * FROM dbo.PersEmail WHERE PersEmail_inaktuell = 0) AS persemail2
										WHERE		Pers_ID = P.Pers_ID)))

RETURN

Und genau diesen Code will ich jetzt auf die OLTP-Technik umstellen. Wichtig ist dabei, dass der Treffer nie zwei E-Mailadressen ergeben darf, da es sonst Probleme gibt. Wenn also ein Datum der letzten Änderung maßgeblich ist, dann müsste die Differenzierung so fein sein, dass jeglicher Doppelwert ausgeschlossen. Das gilt sogar dann, wenn zwei E-Mailadressen maschinell direkt nacheinander angelegt wurden und die Anlagezeit / Änderungszeit praktisch identisch ist.
stefaktiv ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Alt 03.07.2017, 22:19   #10
stefaktiv
Threadstarter Threadstarter
MOF User
MOF User
Standard

Ach ja - noch ein kleiner Test: ich habe einen neuen zusätzlichen Timestamp mit dem Datentyp datetime2(7) erstellt und diesen mit sysdatetime() füllen lassen. Wenn ich jetzt ein Update über beide E-Mailadressen einer Person laufen lasse, dann ist der Wert dieses Timestamps identisch - im Gegensatz zum Datentyp "Timestamp" denn bei dem unterscheiden sich die Inhalte minimal.
stefaktiv ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Alt 06.07.2017, 14:16   #11
sonic8
MOF Profi
MOF Profi
Standard

Zitat: von stefaktiv Beitrag anzeigen

Wichtig ist dabei, dass der Treffer nie zwei E-Mailadressen ergeben darf, da es sonst Probleme gibt. Wenn also ein Datum der letzten Änderung maßgeblich ist, dann müsste die Differenzierung so fein sein, dass jeglicher Doppelwert ausgeschlossen.

Nimm doch einfach ein weiteres, eindeutiges Kriterium hinzu. Die PersEmail_Id würde sich anbieten.
Code:

...
(PE.PersEmail_Id = (SELECT TOP 1 PersEmail_Id
			FROM		 dbo.PersEmail 
			WHERE PersEmail_inaktuell = 0
			AND Pers_ID = P.Pers_ID
			ORDER BY PersEmail_Letzte_Änderung DESC, 
					 PersEmail_Id DESC ))
sonic8 ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Ads
Antworten


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Besucher: 1)
 
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge anzufügen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

vB Code ist An.
Smileys sind An.
[IMG] Code ist An.
HTML-Code ist An.
Gehe zu


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:52 Uhr.


Partner und Co.
Access-Paradies -Alles rund um die Datenbank Microsoft Access -Code -Programme-Tools -Tipps   Kostenlose Tipps & Tricks, Downloads und Programme   www.kulpa-online.com - Tipps - Tricks - Tutorials - Meinungen - Downloads uvm...   vb@rchiv · Willkommen in der Welt der VB Programmierung   Access-Garhammer - Hier finden Sie jede Menge Beispiel-Datenbanken zu Access und mehr ...   mcseboard.de   Die Top Seite für Excel-VBA-Makros uvm.

Powered by: vBulletin Version 3.6.2 (Deutsch)
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.

Copyright ©2000-2010 MS-Office-Forum. Alle Rechte vorbehalten.
Copyright ©Design: Manuela Kulpa ©Rechte: Günther Kramer
Eine Verwendung der Inhalte in anderen Publikationen, auch auszugsweise,
ist ohne ausdrückliche Zustimmung der Autoren nicht gestattet.
Beachten Sie bitte auch unsere Nutzungsbedingungen.