Create multiple views inside a schema - SQL Server - sql-server

How can I create multiple views inside the CREATE SCHEMA statement?
I want to create a SCHEMA, and create two views inside it in the same statement, so all those statements work as a one unit? Succeed or fail together!
From MSDN: http://msdn.microsoft.com/en-us/library/ms189462.aspx
"CREATE SCHEMA can create a schema, the tables and views it contains,
and GRANT, REVOKE, or DENY permissions on any securable in a single
statement. CREATE SCHEMA transactions are atomic. If any error occurs
during the execution of a CREATE SCHEMA statement, none of the
specified securables are created and no permissions are granted."
,
How can I do this? I tried this:
CREATE SCHEMA [MYSCHEMA] AUTHORIZATION [dbo]
CREATE VIEW [VIEW1]
AS
SELECT [ID]
,[NAME]
FROM [dbo].[TABLE1]
/* Here is the Problem */
GO
CREATE VIEW [VIEW2]
AS
SELECT [ID]
,[NAME]
FROM [dbo].[TABLE2]
GO
If I include a GO statement just after first view creation, then script runs but second view VIEW2 is created under the dbo schema, not under MYSCHEMA, and doesn't run as a single unit either.
If I remove the GO after the first view, then it gives an error saying
CREATE VIEW must be the first statement of a batch
for the second CREATE VIEW statement.
How do I solve this and create both views as a part of CREATE SCHEMA statement?

CREATE SCHEMA [MYSCHEMA] AUTHORIZATION [dbo]
CREATE VIEW [VIEW1] AS SELECT [ID], [NAME] FROM [dbo].[TABLE1]
CREATE VIEW [VIEW2] AS SELECT [ID], [NAME] FROM [dbo].[TABLE2]
GO

Related

snowflake: remove access to drop a table to a role

I have created a role with the following grants
GRANT
USAGE,
CREATE FUNCTION,
CREATE PROCEDURE,
CREATE TABLE,
CREATE VIEW,
CREATE EXTERNAL TABLE,
CREATE MATERIALIZED VIEW,
CREATE TEMPORARY TABLE,
ON SCHEMA dbname.schemaname TO ROLE role_test;
Now using this role, i am able to create table or replace a table and also drop a table.
How to stop someone to DROP table.
The owner role of the table will have DROP permissions. So it's not possible to stop someone from dropping the table they created.
You may need to change the ownership of the table to another role.
https://community.snowflake.com/s/article/how-to-drop-an-object-as-a-role-other-than-the-object-creator

Create a copy of a table with data without logging

Is there an easy way to copy the data of a table to the same database with different table name without logging.
CREATE TABLE SCHEMA.NEW_TB LIKE SCHEMA.OLD_TB;
INSERT INTO SCHEMA.NEW_TB (SELECT * FROM SCHEMA.OLD_TB);
The above 2 statements will work but the table contains huge amount of data. So is it possible to copy the data without logging?
Use the following with auto commit switched off in your session:
CREATE TABLE SCHEMA.NEW_TB LIKE SCHEMA.OLD_TB;
COMMIT;
ALTER TABLE SCHEMA.NEW_TB ACTIVATE NOT LOGGED INITIALLY;
INSERT INTO SCHEMA.NEW_TB
SELECT * FROM SCHEMA.OLD_TB;
COMMIT;
It’s important to use ALTER TABLE and INSERT in the same transaction.

SQL Server ownership chain cross schema with different owners for view selecting from multiple schemas

I have 1 database with multiple schemas, some owned by a different user than the default 'dbo' user.
I have a view in one of these 'dbo' schemas, that selects from 5 tables in other 'dbo' schemas, and then 2 tables in a 'UserA' schema.
I want to grant a user group access to the view in the 'dbo' schema and not the underlying tables. When granting permission to the view, I get errors saying cannot select from the tables owned by 'UserA'. Understandable and expected because the view (and thus authorizations granted) are for 'dbo'. So how do I also grant access to the 'UserA' tables without directly assigning them to my user group.
Any recommendations? I tried to find if there is some way to grant access to the view through both 'dbo' and 'UserA', but it seems only 1 owner can grant select permissions? I also tried making views of the 'UserA' table in the 'dbo' schema and then granting permission to those new 'dbo' views, but that didn't work either.
No permissions on the underlying tables are needed when all objects involved are owned by the same user. This is known as ownership chaining in SQL Server.
It seems you have different schemas which are owned by different users, breaking the chain. Tables are owned by the schema's owner by default (i.e. inherited) but this can be overridden by changing the owner at the table level for specialized requirements. Below is an example script that illustrates this method.
Using granular object ownership rather than inheriting the schema owner is not something that should be done routinely. It is not intuitive for most and adds administrative burden.
USE tempdb;
GO
CREATE USER UserA WITHOUT LOGIN;
GRANT CREATE TABLE TO UserA;
CREATE USER UserB WITHOUT LOGIN;
GRANT CREATE TABLE TO UserB;
CREATE USER UserC WITHOUT LOGIN;
CREATE ROLE YourUserGroup;
ALTER ROLE YourUserGroup ADD MEMBER UserC;
GO
CREATE SCHEMA UserA AUTHORIZATION UserA;
GO
CREATE SCHEMA UserB AUTHORIZATION UserB;
GO
CREATE TABLE dbo.Table1(ID int NOT NULL CONSTRAINT PK_Table1 PRIMARY KEY);
GO
EXECUTE AS USER = 'UserA';
GO
CREATE TABLE UserA.Table1(ID int NOT NULL CONSTRAINT PK_Table1 PRIMARY KEY);
GO
REVERT;
GO
EXECUTE AS USER = 'UserB';
GO
CREATE TABLE UserB.Table1(ID int NOT NULL CONSTRAINT PK_Table1 PRIMARY KEY);
GO
REVERT;
GO
CREATE VIEW dbo.View1
AS
SELECT
t1.ID AS dboTable1ID
, t2.ID AS UserATable1ID
, t3.ID AS UserBTable1ID
FROM dbo.Table1 AS t1
JOIN UserA.Table1 AS t2 ON t2.ID = t1.ID
JOIN UserB.Table1 AS t3 ON t3.ID = t2.ID;
GO
GRANT SELECT ON dbo.View1 TO YourUserGroup;
GO
EXECUTE AS USER = 'UserC';
GO
--this fails due to broken ownership chain
SELECT * FROM dbo.View1;
GO
REVERT;
GO
--change table owner to common owner
ALTER AUTHORIZATION ON OBJECT::UserA.Table1 TO dbo;
ALTER AUTHORIZATION ON OBJECT::UserB.Table1 TO dbo;
GO
EXECUTE AS USER = 'UserC';
GO
--this now succeeds because all objects involved are owned by dbo
SELECT * FROM dbo.View1;
GO
REVERT;
GO
DROP VIEW dbo.View1;
DROP TABLE dbo.Table1;
DROP TABLE UserA.Table1;
DROP TABLE UserB.Table1;
DROP SCHEMA UserA;
DROP SCHEMA UserB;
DROP USER UserA;
DROP USER UserB;
DROP USER UserC;
GO

How do I create a user in SQL-Server that only has access to one table, and can only insert rows

I have an SQL server database, with soon to be two databases, which I use for a website.
I already have a user account which is read-only for database 1 to search our products inventory. I'd like to create a seperate account for database 2 only, for table 1 ONLY, that ONLY allows inserting records (no update or delete or anything else). Im trying to be as redundant as possible with access restrictions (on top of code to try and prevent sql injection, if someone were to somehow get something through, I dont want the database itself to allow it).
So bottom line question, How do I create a user in SQL server that has restricted access to only x table in y database and can only read/insert records, and nothing else?
create the user, don't give any roles like db_datareader or db_datawriter
then GRANT INSERT ON YourTable TO SomeUser
if you want insert and select
GRANT INSERT, SELECT ON YourTable TO SomeUser
(1) To give a user with limited access to one Table only
GRANT SELECT ON [schemaName].[tableName] to [username]
Go
(2) To grant INSERT Permission.
GRANT INSERT ON [schemaName].[tableName] TO [username]
Syntax for granting access to a single table:
GRANT access_type ON table_name TO [user name]
Syntax for revoking access for a single table:
REVOKE access_type ON table_name FROM [user name]
where access_type can be SELECT, INSERT, DELETE...
Grant select on dbname.dbo.tablename to username
it giving this error :
Cannot find the object 'APP_TBL_Log', because it does not exist or you do not have permission.
I am logged on as "sa"

Tables created by default in user schema

In Sql Server 2008, when I create a table without schema prefix:
create table mytable ( id int identify )
it usually ends up in the schema dbo, with name dbo.mytable.
However, on one of our servers, the tabel ends up belonging to me:
andomar.mytable
Which configuration difference could explain this?
It depends what your default schema is within that database. Even in SQL Server 2005, if your default schema in that one database is andomar, then any tables created without an explicit schema will end up there.
Check the user properties in that database (not the login properties) and see what the default schema is.
If you don't define schema in which you create table it will always use default one.
you can create it like this:
USE DataBaseName -- define database to use
GO
BEGIN TRAN - if you will have any error everything will roll back
CREATE TABLE testovi.razine - schema name is "testovi" and tablename is "razine"
(
id INT NOT NULL IDENTITY(1,1),
razina NVARCHAR(50) NULL,
razinaENG NVARCHAR(50) NULL,
kreirao UNIQUEIDENTIFIER NULL,
VrijemeKreiranja DATETIME NULL
)
ON [PRIMARY]
GO
When you create table always set constraint and index on column most used for transaction
ALTER TABLE testovi.razine ADD CONSTRAINT
PK_mat_razine PRIMARY KEY CLUSTERED
(id) WITH(IGNORE_DUP_KEY=OFF, --check duplicate and don't ignore if try to insert one
STATISTICS_NORECOMPUTE=OFF, -- important for statistic update and query optimization
ALLOW_PAGE_LOCKS=ON) -* I believe that this is default, but always put it to on if not
ON [PRIMARY]
GO
if ##error<>0
BEGIN
ROLBACK TRAN
END
ELSE
BEGIN
COMMIT TRAN --if everything passed o.k. table will be created
END
If you want to set default schema you have to know that it is user based default so you can set it with code:
USE espabiz -- database;
ALTER USER YourUserName WITH DERAULT_SCHEMA = SchemaName; -- SchemaName is default schema for defined user
Ping if you need additional help or mark answer it you find it usable :)

Resources