Archiv

Archiv für die Kategorie ‘Datenbank’

SQL User mit Login verbinden

12. Februar 2014 Keine Kommentare

Regelmäßig nach einer Wiederherstellung einer bestehenden Datenbank auf einem neuen Server müssen die Logins, die serverseitig gespeichert und angelegt werden, mit dem User der Datenbank verbunden werden. Ansonsten erhält der Login auf die Datenbanken einfach keinen Zugriff.

Dafür gibt es drei Möglichkeiten:

  • Man kann den User in der Datenbank entfernen und den User einfach auf Serverebene neu anlegen. Das SQL Managmentstudio bietet hierbei die Möglichkeit, die Rechte auf einer Datenbank zu erteilen. Aber dabei verliert man ALLE bereits konfigurierten Rechte, die der User in der Datenbank hatte. Diese Lösung ist somit nicht empfehlenswert.
  • Der Microsoft SQL Server bietet die Procedure sp_change_users_login, mit der ein neu angelegter Login im Server mit dem User der Datenbank verbunden werden kann. Ich nehme dafür eigentlich immer einen identischen Namen, um Verwechslungen zu vermeiden:
    EXEC sp_change_users_login 'Update_One', 'User1', 'User1';

    Dieser Befehl muss für jeden User in jeder Datenbank ausgeführt werden, kann aber leicht in einem Skript vorbereitet werden.

  • Abgelöst wird diese vorstehende Procedure durch folgenden SQL Befehl: ALTER USER. In der Anwendung kann man dann schreiben:
    ALTER USER User1 WITH LOGIN = User1;

    Auch dieser Befehl muss für jeden User in jeder Datenbank ausgeführt werden und kann leicht in einem Skript vorbereitet werden.

KategorienDatenbank Tags:

SQL Deadlock durch Autoclose

9. Januar 2014 Keine Kommentare

Seit einigen Monaten nervte in einer Microsoft SQL 2008 Datenbank ein Problem, welches gelegentlich auftrat. Auf die betreffende Datenbank waren ab einem scheinbar zufälligen Zeitpunkt keine schreibenden Zugriffe mehr möglich, lesende Zugriffe aber schon. Ein einfacher Blick nach der Verfügbarkeit reichte also nicht, um die Lauffähigkeit der Datenbank zu testen.

Ein Blick in die Log-Dateien brachte die Erkenntnis, dass diese Datenbank ziemlich oft gestartet wurde (im Gegensatz zu den anderen Datenbanken) und plötzlich ein Fehler 1205 auftrat:

Transaction (Process ID …) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

Danach war die Datenbank schreibend nicht mehr verfügbar, der Fehler 9001 trat auf:

The log for database ‘…’ is not available. Check the event log for related error messages. Resolve any errors and restart the database.

Select – Abfragen waren davon aber nicht betroffen, da diese ja keine Log-Einträge erzeugen.

Die Lösung wurde in SQL ServerCentral.com beschrieben: Abschalten der Option AutoClose in den Eigenschaften der Datenbank! Da diese Eigenschaft weder bewußt gesetzt worden war, noch benötigt wurde, konnte das Problem so einfach gelöst werden.

KategorienDatenbank Tags: ,

Administratorzugriff auf SQL Server wiederherstellen

18. September 2013 Keine Kommentare

Manchmal ist man in der Situation, dass man keinen Zugriff mehr auf einen SQL Server mehr hat, obwohl man selbst Administrator der darunter liegenden Windows-Version ist. In diesem Fall hat Microsoft dafür gesorgt, dass man recht einfach die Administrationsrechte für den SQL Server erlangen kann. Der meiner Meinung nach einfachste Weg geht so:

SQL-Server-KonfigurationsmanagerMan startet den SQL-Server-Konfigurationsmanager und öffnet die Eigenschaften des gewünschten SQL-Dienstes. Bei aktuellen Version hat man nun die Möglichkeit, direkt den Parameter -m hinzuzufügen. Dieser Parameter startet den SQL-Server Einzelbenutzermodus und gibt allen lokalen Administratoren Zugriff. Alternativ muss man bei älteren Versionen auf der Seite erweitert den Parameter direkt in der Auflistung angeben. Aber Achtung, dort werden die Parameter mit ; getrennt. Es muss dann also lauten:

-m;--dC:\Program Files\Microsoft S...

Anschließend muss der Dienst neu gestartet werden. Nun kann man sich mit dem SQL Server Managementstudio direkt verbinden. Aber auch hier Achtung: Das Programm muss dazu unbedingt als Administrator gestartet werden, selbst wenn unter Windows als Admin angemeldet ist! Nun kann man seinen Admin-Login hinzufügen und mit den notwendigen Rechten versehen. Zum Abschluss nicht vergessen, den Parameter -m wieder zu entfernen, damit der Server normal zur Verfügung steht.

KategorienDatenbank Tags: ,

Bestimmen einer Zeitdifferenz mit SQL

24. Oktober 2011 Keine Kommentare

Eine Abfrage im SQL Server enthält eine time-Spalte:

SELECT [Activity], [Duration] FROM TableName

Die Aufgabenstellung bestand darin, die Zeiten zu addieren. Leider wurde dieser Versuch

SELECT SUM([Duration]) FROM TableName

abgelehnt:

Der Operanddatentyp time ist für den sum-Operator ungültig.

was zwar nicht einleuchtend, aber auch nicht zu ändern war.
Die Lösung war die vorherige Umwandlung der Zeit in eine Datumsdifferenz vom Typ Minuten:

SELECT SUM(DATEDIFF(MINUTE, '00:00:00', [Duration])) FROM TableName
KategorienDatenbank Tags:

VistaDB.Net’s letzte Aktualisierung

29. August 2010 Keine Kommentare

Leider hat der Hersteller von VistaDB den Vertrieb dieser Datenbank eingestellt. Als kleinen Trost konnte man zum Abschluss noch den Sourcecode sehr günstig erwerben und mit diesem auch eine unverschlüsselte Version ohne Lizenzabfragen herunterladen.

Im Folgenden möchte ich den somit letzten Umstieg von VistaDB.Net 3 auf 4.1, die bei mir noch in einigen Projekten aktiv ist, zeigen:

1. Installation von VistaDB.Net 4.1. Diese Version 4.1 ließ sich problemlos parallel zur Version 3 installieren und nutzen.

2. Upgraden der Datenbank auf die 4er Version. Das geht im VistaDB Data Builder im Menü Database unter dem Punkt Upgrade VDB3 Database sehr einfach. Leider ändert sich die Dateiendung von .vdb3 auf .vdb4. Setup-Skripte müssen hier evtl. auch angepasst werden.

3. Öffnen der Projekte in Microsoft Visual Studio. In den Projekten ist ein Verweis auf VistaDB.NET20 vorhanden. Dieser wird entfernt und durch den VistaDB 4 Provider ersetzt.

4. Die Datasets (.xsd) müssen in einem externen Editor geöffnet werden, um den XML-Code direkt zu bearbeiten. Man findet darin mindestens einmal Provider=”VistaDB.NET20″, was durch Provider=”System.Data.VistaDB” ersetzt werden muss.

5. Jetzt kommt der schwierigste Teil. Die Connectionstrings müssen aktualisiert werden und die Datasets nochmal neu geschrieben werden. Dazu reicht es eigentlich, den Connectionsstring in den Einstellungen auf die neue Datei (die Dateiendung hat sich ja geändert) zu setzen und einen TableAdapter im Dataset neu zu konfigurieren (ohne Änderung). Jedoch war bei mir das Problem, dass die ConnectionsStrings nicht mehr gültig waren. Das ist zwar ein Problem von Visual Studio und nicht von VistaDB, es steht hier aber trotzdem im Weg. Darum gehe ich einen anderen Weg. Darum habe ich einen anderen Weg gewählt.

Ich habe mir den Namen des Connectionstrings notiert und ihn aus den Einstellungen gelöscht. Dann habe ich ein neues Dataset erzeugt und dort den Connectionstring neu eingegeben und unter dem alten Namen gespeichert. Damit wurde dann als Dummy ein Tableadapter konfiguriert. Das Dataset kann zum Schluss wieder gelöscht werden. Nun können die alten Datasets geöffnet und ein Tableadater neu erzeugt werden.

KategorienDatenbank, Microsoft .NET Tags:

SQL Count, das unbekannte Wesen

5. August 2009 Keine Kommentare

Bei der Suche nach einem praktischen SQL-Skript für eine Statistik, bin ich auf die Möglichkeit gestoßen, den SQL Count Befehl zu verwenden:

SELECT a.BewertungId, 	
 COUNT(*) Gesamt,
 COUNT(E_Datum) Offen, 
 COUNT(CASE WHEN ((a.Abgelehnt = 0) OR (b.OFI = 0)) THEN NULL ELSE 1 END) Abgelehnt
FROM Aktivitaeten a, Bewertung b
WHERE a.BewertungId = b.Id
GROUP BY a.BewertungId
ORDER BY a.BewertungId

Die Nutzungsmöglichkeit des COUNTs ist dabei vielfältig:

  • Üblicherweise wird Count mit dem Parameter (*) aufgerufen. Dieser Aufruf führt zur vollständigen Zählung der Datenmenge.
  • Gibt man aber als Parameter einen Spaltennamen ein, so werden nur die Datensätze gezählt, die in der gewünschten Spalte einen Eintrag ungleich NULL haben.
  • Aber auch die Angabe eines Ausdrucks, der NULL oder einen Wert liefert, ist möglich.

Das aufgeführte Beispiel zählt also auf einmal: alle Datensätze, alle Datensätze mit einem Eintrag in der Spalte E_Datum und als letzten Punkt alle Datensätze, die eine Ablehnung enthalten.
kick it on dotnet-kicks.de

KategorienDatenbank Tags:

Alle Datenbanken vom MSSQL sichern

14. November 2008 Keine Kommentare

Immer wieder habe ich den Fall gehabt, eine Sicherung eines Microsoft SQL Servers einzurichten. Dabei ging es meist nur um kleine Datenbanken, manchmal sogar unter der MSDE 2000 oder dem SQL Server 2005 Express. Dazu wurden dann einfach die Dienste gestoppt und die Dateien wegkopiert.

Gerade auf Webserver war die Lösung unbefriedigend. Darum habe ich mir eine neue Lösung gebastelt. Der SQL-Server bietet zwei Kommandozeilenbefehle: bcp und osql.

bcp bietet einem die Möglichkeit, die Ausgabe eines SQL-Befehls in eine Text-Datei zu leiten. Nutzt man nun einen Select, um alle Datenbank zu ermitteln:

SELECT [name] FROM master..sysdatabases

und erweitertert das Ergebnis um den BACKUP DATABASE Befehl, so hat man eine gute Möglichkeit, sich ein Backupskript dynamisch zu erzeugen:

bcp "Select N' use master', N'GO' UNION Select N'BACKUP DATABASE [' + [name] + N'] TO DISK = N''C:\BackupDB\' + [name] + N'.bak'' WITH FORMAT', N'GO' From master..sysdatabases"
 queryout C:\BackupDB\backupskript.sql -S ".\SQLEXPRESS" -T -c -t \r\n

Das sieht ein wenig unübersichtlich aus, da man jeden Befehl in eine neue Zeile bekommen muss (-t \r\n) und zudem nach jedem BACKUP DATABASE Befehl einen GO benötigt. Ist der Befehl durchgelaufen, sollte das Backupskript vorliegen.

Nun ist nur noch dafür zu sorgen, dass das Skript auch aufgerufen wird:

osql -S .\SQLEXPRESS -E -i C:\BackupDB\backupskript.sql

Läuft alles problemlos durch, wird so bei dem Aufruf beider Befehle ein vollständiges Backup alle Datenbanken des angegebenen SQL-Servers gemacht. Getestet habe ich es mit dem Microsoft SQL Server 2005, der MSDE 2000 und dem Microsoft SQL Server 2005 Express Edition.

KategorienDatenbank Tags: ,

Master-Detail Update Probleme

5. November 2008 Keine Kommentare

Dank Visual Studio und Microsoft .NET in der Version 2 ist es ein leichtes, eine Master-Detail-Beziehung zwischen zwei Tabellen in einem Dataset nachzubilden und auch im Formular zu bearbeiten. Die Erstellung des Datasets übernimmt ein Assistent. Die Controls im Formular werden per Drag&Drop platziert. Dabei wird im Code auch automatisch Code zur Aktualisierung der Datenbank angelegt:

 myMasterTableBindingSource.EndEdit();
 myDetailTableBindingSource.EndEdit();
 tableAdapterManager.UpdateAll(dataSetmyTables);

Soweit, so gut. Leider kann sich für den Anwender dadurch Datenverlust ergeben. Wir ein Detail-Datensatz bearbeitet und dann der Master-Datensatz gewechselt, so bleibt der Detail-Datensatz im Edit-Modus! Mit

 myDetailTableBindingSource.EndEdit();

ist dieser Datensatz nicht mehr zu erreichen und wird auch nicht beim UpdateAll berücksichtigt. Eine Abhilfe schafft hier:

 for (int i = 0; i < dataSetmyTables.myMasterTable.Count; i++)
   { dataSetmyTables.myMasterTable[i].EndEdit(); }
 for (int i = 0; i < dataSetmyTables.myDetailTable.Count; i++) 
   { dataSetmyTables.myDetailTable[i].EndEdit(); }
 tableAdapterManager.UpdateAll(dataSetmyTables);
KategorienDatenbank, Microsoft .NET Tags:

ConnectionString zur Laufzeit setzen

7. Oktober 2008 Keine Kommentare

ConnectionStrings werden von Visual Studio automatisch in die Anwendungseinstellungen übernommen und beinhalten bei lokalen Datenbanken (beispielsweise VistaDB) üblicherweise auch den absoluten Pfad. Für Asp.Net bietet sich wohl eine solche Lösung an:

Data Source=|DataDirectory|\MyDatabase.vdb3

Das funktioniert aber nicht bei WinForm-Anwendungen, weil es das DataDirectory dort nicht gibt. In dem Falle kann man den ConnectionString aber für die Entwicklungsumgebung fix setzen und dann einfach zur Laufzeit korrigieren:

string connString = global::MyLib.Properties.Settings.Default.ConnectionStringMyApp;
string dbName = "MyDatabase.vdb3";
Int32 startPos = connString.IndexOf("Data Source =\"") + 13;
Int32 endPos = connString.IndexOf(dbName + "\"") + dbName.Length;
connString = connString.Substring(0, startPos + 1) +
 "D:\\MyDataDir\\" + dbName + connString.Substring(endPos);
global::MyLib.Properties.Settings.Default["ConnectionStringMyApp"] = connString;

Das funktioniert, wenn man weiß, dass die Properties in den Settings problemlos über Default[] beschrieben werden können.