Why schema is required while creating a table and not while querying a table - SQL server - sql

I'm new to the MS SQL server. Our client has given us a SQL server DB and for this DB they have configured the Service Principal Authentication. So I logged into the DB using my client company account and then I tried to create a table without giving any schema name. for example
CREATE TABLE visits (
visit_id INT PRIMARY KEY IDENTITY (1, 1),
first_name VARCHAR (50) NOT NULL,
last_name VARCHAR (50) NOT NULL,
visited_at DATETIME,
phone VARCHAR(20),
store_id INT NOT NULL,
);
so when I ran this query it gave me the below error
Msg 2760, Level 16, State 1, Line 1
The specified schema name "aashay.amballi#<company>.com" either does not exist or you do not have permission to use it.
so now when I created the table with DBO schema it created the table.
CREATE TABLE dbo.visits (
visit_id INT PRIMARY KEY IDENTITY (1, 1),
first_name VARCHAR (50) NOT NULL,
last_name VARCHAR (50) NOT NULL,
visited_at DATETIME,
phone VARCHAR(20),
store_id INT NOT NULL,
);
So now when I tried to query this visits table without any schema (i.e. DBO) select * from visits it actually gave me the result.
Also when I ran the select SCHEMA_NAME() to check what is the default schema, it returned null. So is there a possibility that when there is no default schema that is set for a user and while creating a table without a schema name it will give that error? if that is the case then while querying without any schema how it's picking the dbo schema by default?
So I'm a bit confused about how this is working. Can anyone please explain this?
This question is regarding the question that I asked a couple of days back when I'm trying to integrate MSSQL with service principal authentication with the Django Framework - Django MigrationSchemaMissing exception on Azure SQL using service principal auth

From the CREATE TABLE description:
If type_schema_name isn't specified, the SQL Server Database Engine
references type_name in the following order:
The SQL Server system data type.
The default schema of the current user in the current database.
The dbo schema in the current database.
And what is your default schema? It depends on options of CREATE USER statement used when creating your user's account:
WITH DEFAULT_SCHEMA = schema_name Specifies the first schema that will
be searched by the server when it resolves the names of objects for
this database user.
You can skip the schema in queries, but it is a best practise to always use schemas.

Related

How do I create a postrgresql database using SQL's DDL on pgadmin4?

I'm learning DDL to create and define an SQL database with Postgresql 10.
I have the something like the following SQL code in an .sql file, and I want to input it in psql or PgAdmin 4, just to test the syntax and see the database structure:
CREATE DATABASE database;
CREATE TYPE t_name AS
( first VARCHAR(30),
last VARCHAR(60)
);
CREATE TABLE telephone_m
( tnumber VARCHAR(15) NOT NULL UNIQUE
);
CREATE TABLE people
( curp CHAR(18) NOT NULL PRIMARY KEY,
pname t_name NOT NULL,
birth_date DATE NOT NULL,
telephone_m VARCHAR(15) REFERENCES telephone_m
);
CREATE TABLE clients
( curp CHAR(18) NOT NULL PRIMARY KEY,
cid SERIAL NOT NULL REFERENCES cards,
clocation VARCHAR(29)
) INHERITS (people);
CREATE TABLE cards
( cid BIGSERIAL NOT NULL PRIMARY KEY,
curp CHAR(18) NOT NULL REFERENCES clients,
trips SMALLINT,
distance NUMERIC,
points NUMERIC
);
CREATE TABLE drivers
( curp CHAR(18) NOT NULL PRIMARY KEY,
rfc CHAR(22) NOT NULL UNIQUE,
adress t_adress NOT NULL
) INHERITS (people);
I've tried in PgAdmin 4 making right-click on a new database -> CREATE Script, it opens Query Editor, I copy paste my code and execute it, but it returns:
ERROR: CREATE DATABASE cannot be executed from a function or multi-command string
SQL state: 25001
I've also tried using Query Tool directly from the PgAdmin tools menu with the same results.
The database is created just fine. But if you want to create object in the new DB, you have to connect to it. In any client, including pgAdmin4.
And you cannot run CREATE DATABASE inside of a transaction. Must be committed on it's own. Executing multiple commands at once is automatically wrapped into a single transaction in pgAdmin.
You have to execute CREATE DATABASE mydb; on its own (for instance by selecting only that line and pressing F5 while being connected to any DB, even the maintenance db "postgres". Then click on "Databases" in the object browser in the pgadmin4 main window / tab, hit F5 to refresh the view, click on the new DB, open up a new query tool with the flash icon (in a new window / tab) and execute the rest of your script there.
psql scripts manage by using the meta-command \c to connect to the new db after creating it, within the same session.
Asides:
"database" is no good name for a database.
CREATE TYPE AS (...), but just CREATE TABLE (...). No AS.
And you typically don't want to use the data type CHAR(18). See:
Any downsides of using data type "text" for storing strings?
Get sum of integers for UNIQUE ids
What is the overhead for varchar(n)?
Should I add an arbitrary length limit to VARCHAR columns?
There is the ; missing after the CREATE DATABASE database (and perhaps give the db a better name).

Msg 2760, Level 16, State 1, Line 5 The specified schema name "items" either does not exist or you do not have permission to use it

I am trying to create a temporal table in my SQL Server database. Is anyone familiar with this error in SQL Server:
Msg 2760, Level 16, State 1, Line 5
The specified schema name "items" either does not exist or you do not have permission to use it.
I think there may be something wrong with my user privileges. Any help would be great.
Here's the code:
CREATE TABLE [items].[items_Temporal](
[itemsID] [int] NOT NULL,
[item_Name] [varchar](50) NOT NULL,
[item_Number] [int] NOT NULL,
[item_Price] [float] NOT NULL,
ValidFrom datetime2(7) GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
ValidTo datetime2(7) GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
CONSTRAINT [PK_items_Temporal_items1ID] PRIMARY KEY CLUSTERED
(
[itemsID] ASC
),
PERIOD FOR SYSTEM_TIME(ValidFrom, ValidTo)
)
WITH(SYSTEM_VERSIONING = ON (HISTORY_TABLE = [items].[items_Temporal_History]));
From the answer of Yogesh, you can find whether the schema exists or not.
If the schema items not exist, try running
CREATE SCHEMA items
If you don't have permission to create Schema,
USE <database_name>;
GRANT CREATE SCHEMA TO <user_name>;
GO
Then create schema and run the code for creating the table.
In the case you have the schema and you are not having the permission to use it,
USE <database_name>;
GRANT CREATE TABLE TO <user_name>;
GO
Then run the code to create table.
Read Docs here
Run below query to check actually your are trying to run query in database has item schema in it or not
SELECT * FROM sys.schemas WHERE name = 'item'
If you have rows in above query then check login user from which you are trying to run this query. Also check does this user has rights to create table by this way you will have idea why this error is coming

Cretae Domains Table In HSQL includes the metadata of Domains Sytem View

I want to create a table named Domains in HSQL. But when i try to do so it includes 29 columns although my table definition specifies just 5.There is a Domains System View and it seems it is including these columns also in my metadata.Because of this i am not able to insert anything in my db as those unwanted columns from Domains System View also contain some non-null values.
I tried creating schema but it is not what i need as my solution.
I need to override this Domains System View or stop the metadata from picking it.
Does anyone know how can we do it?
I am stuck at it for more than few days now.
CREATE TABLE IF NOT EXISTS Domains
(
domain_id INTEGER NOT NULL,
name VARCHAR(100) NOT NULL,
description VARCHAR(500) NOT NULL,
CREATED_BY VARCHAR(8) NOT NULL,
LAST_UPDATED_BY VARCHAR(8) NOT NULL,
PRIMARY KEY (domain_id)
);

"There is already an object named XXXX in the database" after creating New database

I have an SQL file which I am executing on an SQL Server instance which contains the schema for a database. The file creates a brand new database (as in, a database with this name does not exist on this server):
CREATE DATABASE PROJECT;
and begins to create a relation:
CREATE TABLE Courses (
CourseID INT NOT NULL PRIMARY KEY,
Name VARCHAR(64) NOT NULL UNIQUE,
Code CHAR(4) NOT NULL UNIQUE
);
...
and here is what SQL Server tells me right off the bat:
Msg 2714, Level 16, State 6, Line 3
There is already an object named 'Courses' in the database.
Any idea why SQL Server tells me that there already exists a relation by the name of Courses when clearly there isn't?
Thank you for your time.
Check the database if you are using PROJECT
CREATE DATABASE PROJECT
GO
USE PROJECT
GO
CREATE TABLE Courses
(
CourseID INT NOT NULL PRIMARY KEY,
Name VARCHAR(64) NOT NULL UNIQUE,
Code CHAR(4) NOT NULL UNIQUE
)
GO
You are likely missing USE PROJECT statement and therefore trying to create Courses table in the master database, not in the PROJECT database.
Long shot but try using:
Use project;
CREATE TABLE Courses....

Passing information from views to base tables in Oracle (SQL)

I have a slight problem!
I have an original base table "StaffAddressDetails":
CREATE TABLE StaffAddressDetails
(ContactID INTEGER NOT NULL,
Postcode VARCHAR (10) NOT NULL,
HouseNameOrNumber VARCHAR (50) NOT NULL,
Street VARCHAR (50) NOT NULL,
Street2 VARCHAR (50) DEFAULT '...',
Town VARCHAR (50) NOT NULL,
County VARCHAR (50) NOT NULL,
Country VARCHAR (50) NOT NULL,
StaffID INTEGER NOT NULL,
CONSTRAINT StaffAddressDetails_PK PRIMARY KEY (ContactID, Postcode),
CONSTRAINT StaADContactIDSCD FOREIGN KEY (ContactID)
REFERENCES StaffContactDetails (ContactID));
I want the members of staff to be able to see only their own details, so I have a created a view "HDPBHTTSKStaffAddDetsForSelf" and granted that view to a role "Teacher":
CREATE VIEW HDPBHTTSKStaffAddDetsForSelf AS
SELECT * FROM StaffAddressDetails
WHERE StaffID IN
(SELECT USER
FROM DUAL);
...and...
GRANT SELECT, INSERT, UPDATE ON HDPBHTTSKStaffAddDetsForSelf TO Teacher;
That all works fine - the problem comes when inserting a new row (when logged in on a teacher's account) should, say, the teacher acquire a new address and wish to add it to the school system.
The inserted row appears when queried from that teacher's account, but does not pass down to the original base table, meaning no-one except the teacher can see it, not even admin.
Is there a quick fix??
Many thanks in advance,
Zulu
You should use the WITH CHECK OPTION when creating your view, so that Teacher role members cannot insert or update data with different StaffID than their own, i.e.
create view ... as select ... from ... where ... WITH CHECK OPTION;
Further, agreeing with #danihp, only reason I see why data seem not being passed down to the table for the admin to see, is that inserting transaction is not being committed.
According to my "Pro Oracle Database 11g Administration" book:
If you don't want a user to be able to perform INSERT, UPDATE, or
DELETE operations on a view, then don't grant those object privileges
on the underlying table(s) to that user.
Of course, you want to allow DML operations to the underlying table. To me, that says you also need to make sure that the "Teacher" has appropriate permissions on the StaffAddressDetails table, as well.
GRANT SELECT, INSERT, UPDATE ON StaffAddressDetails TO Teacher;
And to echo Carl's answer, it's a good idea to create this type of view using WITH CHECK OPTION.