Proper syntax for deploying a certificate in database project - sql-server

How can I have a certificate in a Visual Studio 2010 database project that will be created, updated and removed depending on changes in the project similar to the way that it handles tables, stored procedures, keys and other objects?
Below is the syntax that I am currently using, and the $(CertName).
CREATE CERTIFICATE [$(CertName)]
AUTHORIZATION [dbo]
WITH SUBJECT = N'Encrypt Data', START_DATE = N'11/26/2012 15:13:03', EXPIRY_DATE = N'11/26/2013 15:13:03'
ACTIVE FOR BEGIN_DIALOG = ON;
I have tried to check if it exists using the below if statement.
IF (select Count(*) from sys.symmetric_keys where name like '$(CertName)') = 0
BEGIN
--insert create statement
END
However using this approach I get the following errors, due to the fact that I use the certificate in the definition of the symmetric key.
SQL03006: Symmetric Key: [$(KeyName)] has an unresolved reference to Certificate [$(CertName)].

Try this:
IF EXISTS (SELECT 1 FROM sys.certificates where name = '$(CertName)')

Related

Azure SQL: Adding from Blob Not Recognizing Storage

I am trying to load data from a CSV file to a table in my Azure Database following the steps in https://learn.microsoft.com/en-us/sql/t-sql/statements/bulk-insert-transact-sql?view=sql-server-ver15#f-importing-data-from-a-file-in-azure-blob-storage, using the Managed Identity option. When I run the query, I receive this error:
Failed to execute query. Error: Referenced external data source "adfst" not found.
This is the name of the container I created within my storage account. I have also tried using my storage account, with the same error. Reviewing https://learn.microsoft.com/en-us/sql/relational-databases/import-export/examples-of-bulk-access-to-data-in-azure-blob-storage?view=sql-server-ver15 does not provide any further insight as to what may be causing the issue. My storage account does not have public (anonymous) access configured.
I'm assuming that I'm missing a simple item that would resolve this issue, but I can't figure out what it is. My SQL query is below, modified to not include content that should not be required.
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '**************';
GO
CREATE DATABASE SCOPED CREDENTIAL msi_cred WITH IDENTITY = '***********************';
CREATE EXTERNAL DATA SOURCE adfst
WITH ( TYPE = BLOB_STORAGE,
LOCATION = 'https://**********.blob.core.windows.net/adfst'
, CREDENTIAL= msi_cred
);
BULK INSERT [dbo].[Adventures]
FROM 'Startracker_scenarios.csv'
WITH (DATA_SOURCE = 'adfst');
If you want to use Managed Identity to access Azure Blob storage when you run BULK INSERT command. You need to enable Managed Identity for the SQL server. Otherwise, you will get the error Referenced external data source "***" not found. Besides, you also need to assign Storage Blob Data Contributor to the MSI. If you do not do that, you cannot access the CVS file storing in Azure blob
For example
Enable Managed Identity for the SQL server
Connect-AzAccount
#Enable MSI for SQL Server
Set-AzSqlServer -ResourceGroupName your-database-server-resourceGroup -ServerName your-SQL-servername -AssignIdentity
Assign role via Azure Portal
Under your storage account, navigate to Access Control (IAM), and select Add role assignment. Assign Storage Blob Data Contributor RBAC role to the server which you've registered with Azure Active Directory (AAD)
Test
a. Data
1,James,Smith,19750101
2,Meggie,Smith,19790122
3,Robert,Smith,20071101
4,Alex,Smith,20040202
b. script
CREATE TABLE CSVTest
(ID INT,
FirstName VARCHAR(40),
LastName VARCHAR(40),
BirthDate SMALLDATETIME)
GO
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'YourStrongPassword1';
GO
--> Change to using Managed Identity instead of SAS key
CREATE DATABASE SCOPED CREDENTIAL msi_cred WITH IDENTITY = 'Managed Identity';
GO
CREATE EXTERNAL DATA SOURCE MyAzureBlobStorage
WITH ( TYPE = BLOB_STORAGE,
LOCATION = 'https://jimtestdiag417.blob.core.windows.net/test'
, CREDENTIAL= msi_cred
);
GO
BULK INSERT CSVTest
FROM 'mydata.csv'
WITH (
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n',
DATA_SOURCE = 'MyAzureBlobStorage');
GO
select * from CSVTest;
GO

Get key name in an existing provider

I want to find out what key name provided from an external provider my database is using in an encrypted database.
This is an example taken from Microsoft website.
CREATE ASYMMETRIC KEY EKM_askey1
FROM PROVIDER EKM_Provider1
WITH
ALGORITHM = RSA_2048,
CREATION_DISPOSITION = CREATE_NEW
, PROVIDER_KEY_NAME = 'key10_user1' ;
GO
But I don't know how to learn whether this is CREATE_NEW or OPEN_EXISTING and have no clue what view contains information about this key10_user1 as mentioned in the example.
Could you try:
SELECT * FROM sys.cryptographic_providers;
to get the provider id and then query using sys.dm_cryptographic_provider_keys:
SELECT * FROM sys.dm_cryptographic_provider_keys(1234567);
GO

Litespeed error : Table name must be specified in the format owner_name.table_name

I'm trying to recover a table from Litespeed bakcup. The table is of schema SOURCE. Litespeed object recovery wizard fails with the error:: Table name must be specified in the format owner_name.table_name. I tried with the store procedure directly as well but it's giving the same error. Please help me fix this issue:
EXEC master.dbo.xp_objectrecovery
#filename = 'backup_file_name'
, #filenumber = 1
, #objectname = 'SOURCE.target_rpt_2016'
, #destinationdatabase = 'database_name'
,#destinationtable ='SOURCE.target_rpt_2016_restore'
, #tempdirectory = 'recovery_temp_dir'
I tried giving destinationtable without schema/dbo as well but it's throwing same error.
Atlast figured out the issue.
The owner of the schema Source is a domain account Dom\AXp0101. So when I changed the paramter #ObjectName to '[Dom\AXp0101].[source].[2016_target_rpt_2016]' the recovery completed. Read somewhere that as the owner of this particular schema is a domain account, there might be issues associated with demiliters so we have exclusively specify like above.

How to constrain SQL tables to multiple specific types

I have a small database that I'm developing SQL Server 2008.
I don't have much SQL experience overall, so finding it difficult to find information as to what the appropriate pattern for this issue is.
The main table is 'Provider' a Provider can be a 'MatchService', a 'CompareService', or both depending on 'ProviderTypeId'. I'm looking to contrain data in the MatchService and CompareService tables based on the following rules:
1) A Provider with a ProviderTypeId = Lender can be both a MatchService and a CompareService;
2) A Provider with a ProviderTypeId = Pingtree can only be a MatchService.
I know that a solution probably includes a bridge table in the schema but I'm unsure as to what and where. Any advice appreciated.
Maby something like this:
CREATE TRIGGER MatchService_ITrig
ON MatchService
FOR INSERT
AS
IF NOT EXISTS (
SELECT
ProviderID
FROM
Provider p
INNER JOIN
inserted i ON
P.ID = I.ProviderID
WHERE
ProviderTypeID = 'Lender' OR
ProviderTypeID = 'PingTree'
)
BEGIN
ROLLBACK TRANSACTION
END
How about :
ALTER TABLE CompareService
ADD CONSTRAINT chkPTID CHECK (ProviderTypeId = Lender);
GO
Raj

How to check if SQL Server Tables are System Tables

Using the stored procedure sp_msforeachtable it's possible to execute a script for all tables in a database.
However, there are system tables which I'd like to exclude from that. Instinctively, I would check the properties IsSystemTable or IsMSShipped. These don't work like I expect - I have for example a table called __RefactorLog:
But when I query if this is a system or MS Shipped table, SQL Server reports none of my tables are system tables:
exec (N'EXEC Database..sp_msforeachtable "PRINT ''? = '' + CAST(ObjectProperty(Object_ID(''?''), ''IsSystemTable'') AS VARCHAR(MAX))"') AS LOGIN = 'MyETLUser'
-- Results of IsSystemTable:
[dbo].[__RefactorLog] = 0
[schema].[myUserTable] = 0
and
exec (N'EXEC Database..sp_msforeachtable "PRINT ''? = '' + CAST(ObjectProperty(Object_ID(''?''), ''IsMSShipped'') AS VARCHAR(MAX))"') AS LOGIN = 'MyETLUser'
-- Results of IsMSShipped:
[dbo].[__RefactorLog] = 0
[schema].[myUserTable] = 0
When I look into the properties of the table (inside SSMS), the table is marked as a system object. An object property like IsSystemObject doesn't exist though (AFAIK).
How do I check if a table is a system object, apart from the object property? How does SSMS check if a table is a system object?
Management studio 2008 seems to run some quite ugly following code when opening the "System Tables" folder in the object explorer, the key bit seems to be:
CAST(
case
when tbl.is_ms_shipped = 1 then 1
when (
select
major_id
from
sys.extended_properties
where
major_id = tbl.object_id and
minor_id = 0 and
class = 1 and
name = N''microsoft_database_tools_support'')
is not null then 1
else 0
end
AS bit) AS [IsSystemObject]
(Where tbl is an alias for sys.tables)
So it seems that it's a combination - either is_ms_shipped from sys.tables being 1, or having a particular extended property set.
__refactorlog is, in contrast to what SSMS suggests, a user table. It is used during deployment to track schema changes that cannot be deduced from the current database state, for example renaming a table.
If all your other user tables are in a custom (non-dbo) schema, you can use a combination of the isMSshipped/isSystemTable attributes and the schema name to decide if a table is 'in scope' for your script.
In the past I've worked on the assumption that, in the sys.objects table, column is_ms_shipped indicates whether an object is or is not a system object. (This column gets inherited by other system tables, such as sys.tables.)
This flag can be set by procedure sp_ms_markSystemObject. This, however, is an undocumented procedure, is not supported by Microsoft, I don't think we're supposed to know about it, so I didn't tell you about it.
Am I missing something?
However, there are system tables which I'd like to exclude from that
At least on SQL Server 2008, sp_MSforeachtable already excludes system tables, as this excerpt from it shows:
+ N' where OBJECTPROPERTY(o.id, N''IsUserTable'') = 1 ' + N' and o.category & ' + #mscat + N' = 0 '

Resources