Wie gehe ich ab, wenn ein Datenbankschema existiert?
-
03-07-2019 - |
Frage
Im Rahmen unseres Build -Prozesses führen wir ein Datenbank -Update -Skript aus, während wir Code in 4 verschiedenen Umgebungen bereitstellen. Da die gleiche Abfrage hinzugefügt wird, bis wir eine Veröffentlichung in die Produktion fallen lassen hat Mehrmals in einer bestimmten Datenbank ausführen zu können. So was:
IF NOT EXISTS (SELECT * FROM sys.tables WHERE object_id = OBJECT_ID(N'[Table]'))
BEGIN
CREATE TABLE [Table]
(...)
END
Derzeit habe ich eine Schema -Anweisung im Bereitstellungs-/Build -Skript. Wo frage ich mich nach der Existenz eines Schemas?
Lösung
Suchen Sie sys.schemas?
IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = 'jim')
BEGIN
EXEC('CREATE SCHEMA jim')
END
Notiere dass der CREATE SCHEMA
muss in einer eigenen Charge (per eigene Charge Die Antwort unten)
Andere Tipps
@Bdukes ist richtig auf das Geld für die Bestimmung, ob das Schema existiert, aber die obige Erklärung funktioniert nicht in SQL Server 2005. CREATE SCHEMA <name>
muss in seiner eigenen Charge laufen. Eine Arbeit ist es, die auszuführen CREATE SCHEMA
Anweisung in einem Exec.
Hier ist, was ich in meinen Build -Skripten verwendet habe:
IF NOT EXISTS (SELECT 1 FROM sys.schemas WHERE name = '<name>')
BEGIN
-- The schema must be run in its own batch!
EXEC( 'CREATE SCHEMA <name>' );
END
Nur sein extra "Defensiv", die folgende Version generiert einen Typ -Konvertierungsfehler Schema
"S Ähnlich wie der Validierungscode oft absichtlich Ausnahmen aus wirft, weil ich glaube, dass es gut ist, und ich glaube, es ist" Best Practice ", alle möglichen Rückgabergebnisse zu berücksichtigen, egal wie unwahrscheinlich, und selbst wenn es nur darum geht, eine tödliche Ausnahme zu generieren, weil die bekannten Effekte Die Bearbeitung der Verarbeitung ist normalerweise besser als unbekannte kaskadierende Effekte nicht eingefangener Fehler. Weil es höchst unwahrscheinlich ist, dachte ich nicht, dass es die Mühe eines getrennten Werts wert ist Count
Überprüfen Sie + Throw
oder Try
-Catch
-Throw
So generieren Sie einen benutzerfreundlicheren fatalen Fehler, aber dennoch trotzdem ein tödlicher Fehler.
SS 2005-:
declare @HasSchemaX bit
set @HasSchemaX = case (select count(1) from sys.schemas where lower(name) = lower('SchemaX')) when 1 then 1 when 0 then 0 else 'ERROR' end
SS 2008+:
declare @HasSchemaX bit = case (select count(1) from sys.schemas where lower(name) = lower('SchemaX')) when 1 then 1 when 0 then 0 else 'ERROR' end
Dann:
if @HasSchemaX = 1
begin
...
end -- if @HasSchemaX = 1
Dies ist alt, also fühle ich mich gezwungen, hinzuzufügen: Für SQL Server 2008+ diese alle funktionieren (für den Auswahlteil), dann verwenden Sie dann EXECUTE('CREATE SCHEMA <name>')
Um es tatsächlich zu negativen Ergebnissen zu erstellen.
DECLARE @schemaName sysname = 'myfunschema';
-- shortest
If EXISTS (SELECT 1 WHERE SCHEMA_ID(@schemaName) IS NOT NULL)
PRINT 'YEA'
ELSE
PRINT 'NOPE'
SELECT DB_NAME() AS dbname WHERE SCHEMA_ID(@schemaName) IS NOT NULL -- nothing returned if not there
IF NOT EXISTS ( SELECT top 1 *
FROM sys.schemas
WHERE name = @schemaName )
PRINT 'WOOPS MISSING'
ELSE
PRINT 'Has Schema'
SELECT SCHEMA_NAME(SCHEMA_ID(@schemaName)) AS SchemaName1 -- null if not there otherwise schema name returned
SELECT SCHEMA_ID(@schemaName) AS SchemaID1-- null if not there otherwise schema id returned
IF EXISTS (
SELECT sd.SchemaExists
FROM (
SELECT
CASE
WHEN SCHEMA_ID(@schemaName) IS NULL THEN 0
WHEN SCHEMA_ID(@schemaName) IS NOT NULL THEN 1
ELSE 0
END AS SchemaExists
) AS sd
WHERE sd.SchemaExists = 1
)
BEGIN
SELECT 'Got it';
END
ELSE
BEGIN
SELECT 'Schema Missing';
END