order by clause is different with CHAR(8) AND NVARCHAR(8) columns with Sql Server - sql

I am using SQL Server 2016 and i have the same table structure setup in two databases ie database 1 and database 2. The table structure is the same on both tables for table T, the primary key columns are of char(8) on one and NVARCHAR(8) on the other.
The primary key column is of type CHAR(8) on table T in database 1
The primary key column is of type NVARCHAR(8) on table T in database
2
My primary key has keys as below, they have special characters
'........
'/*-/*-
'/////
'/////...
+65+965+
//
- -
Issue
When I order by the primary key in the two tables i get different order of the keys. How can this be resolved without having to change the column type?
I tried casting the column to the other type but that did not help with ordering.

Related

SQL: How to link two tables that don't share a column name without creating a composite table?

I have to create a database named "Elections" and then write some queries to get the answers provided by my teacher.
I created the database. My issue is that I don't know how to link two tables (candidate and constituency) because they do not share any primary or foreign key.
The teacher is saying that a composite table should not be created in order to link those two tables.
Please see picture (the tables are linked on the pictures but I do not know how to do it when I create the database).
I am also including:
the query that I have to write. The thing is, without knowing how to link those two tables, I cannot write the query.
the SQL code representing the creation of those two tables.
QUERY:
1. Display the number of candidates eliminated in the first
round, for each constituency, and show the constituency number,
and name.
SQL CODE:
CREATE TABLE CANDIDATE (
CANDIDATE_NB smallint CONSTRAINT PK_CANDIDATE_NB PRIMARY KEY NOT NULL,
PARTY_NB smallint NOT NULL,
ROUND tinyint NOT NULL
);
alter table CANDIDATE ADD CONSTRAINT FK_PARTY_NB FOREIGN KEY (PARTY_NB) REFERENCES PARTY(PARTY_NB);
CREATE TABLE CONSTITUENCY (
CONSTITUENCY_NB smallint IDENTITY (100, 100) CONSTRAINT PK_CONSTITUENCY_NB PRIMARY KEY NOT NULL,
CONSTITUENCY_NAME varchar(20) NOT NULL,
NB_REGISTERED smallint NULL,
TOTAL_CANDIDATES smallint NULL
);
I am trying to understand how to link those two tables but I really can't think of anything apart from creating a composite table, which is not what has to be done as per my teacher's instructions.

Unique constraint with foreign key

I have two Postgres tables with the following columns:
Command
Column
Type
id
Integer Primary Key
name
VARCHAR(32)
Option
Column
Type
id
Integer Primary Key
name
VARCHAR(32)
command_id
FOREIGN KEY on COMMAND("id")
I want to add another constraint where the Command name column and the Option command_id columns are tied, such that two commands can share the same name provided they are part of different options. How would I make such a constraint? Would it be better to add no constraint but only allow the backend to make the required checks before entering data?
Edit: I realized that I was overthinking it for my simple use case and that storing a JSON field would be fine enough. However, if the table structure happened to be more complex, then the question would still be valid.
if the name from Command table is the same as name column in Option column. then that column in Option table is redundant and you can always fetch the name by FK that you already have (command_id).
but normally you can use composite key for your FK, for example :
create table Options(
id int primary key
, name varchar(32)
, command_id int
, foreign key fk_name (name , command_id) references Command(name, id)
);
and of course name and id in command table should be part of candidate key.

Best practice for verifying correctness of data in MS SQL

We have multiple tables with different data (for example masses, heights, widths, ...) that needs to be verified by employees. To keep track of already verified data, we are thinking about designing a following table:
TableName varchar
ColumnName varchar
ItemID varchar
VerifiedBy varchar
VerificationDate date
This table links the different product id's, tables and columns that will be verified, for example:
Table dbo.Chairs
Column dbo.Chairs.Mass
ItemId 203
VerifiedBy xy
VerificationDate 10.09.2020
While creating foreign keys, we were able to link the ItemID to the central ProductsID-Table. We wanted to create two more foreign keys for database tables and columns. We were unable to do this, since "sys.tables" and "INFORMATION_SCHEMA.COLUMNS" are views.
How can I create the foreign keys to the availible database tables/columns?
Is there better way how to do such a data verification?
Thanks.
You can add a CHECK constraint to verify that the correctness of the data which is inserted/updated in the columns TableName and ColumnName, like this:
CREATE TABLE Products (
ItemID VARCHAR(10) PRIMARY KEY,
ItemName NVARCHAR(50) UNIQUE
)
CREATE TABLE Chairs (
ItemID VARCHAR(10) PRIMARY KEY,
FOREIGN KEY (ItemID) REFERENCES dbo.Products,
Legs TINYINT NOT NULL
)
CREATE TABLE Sofas (
ItemID VARCHAR(10) PRIMARY KEY,
FOREIGN KEY (ItemID) REFERENCES dbo.Products,
Extendable BIT NOT NULL
)
CREATE TABLE Verifications (
TableName sysname NOT NULL,
ColumnName sysname NOT NULL,
ItemID VARCHAR(10) REFERENCES dbo.Products,
VerifiedBy varchar(30) NOT NULL,
VerificationDate date NOT NULL,
CHECK (COLUMNPROPERTY(OBJECT_ID(TableName),ColumnName,'ColumnId') IS NOT NULL)
)
You need to grant VIEW DEFINITION on the tables to the users which have rights to insert/update the data.
This will not entirely prevent wrong data, because the check constraints will not be verified when you drop a table or a column.
However, I don't think this is necessarily a good idea. A better (and more conventional) way would be to add the VerifiedBy and VerificationDate to the Products table (if you can force the user to verify all the properties at once) or create separate columns regarding each verified column (for example LegsVerifiedBy and LegsVerificationDate in the Chairs table, ExtendableVerifiedBy and ExtendableVerificationDate in the Sofas table, etc), if the verification really needs to be done separately for each column.

Is it possible to create an identity column in Oracle without it being a primary key, and how does it relate to H2 Database?

I'm trying to transform a table to start using natural keys instead of surrogate keys, so before explaining what I'm trying to do, I'll explain how the database is currently set up.
-- FOO_BAR TABLE
id NUMBER(10) PRIMARY KEY, -- A sequence and a trigger is set up to this column.
uuid CHAR(36) UNIQUE
What I'm trying to do is:
The id column should be deleted;
The uuid column should be the primary key;
A new column called creation_order should be created, and it should have the same values as id, but it'll not be the primary key.
So after the migration the table should look like this:
-- FOO_BAR TABLE
creation_order NUMBER(10) UNIQUE GENERATED AS IDENTITY,
uuid CHAR(36) PRIMARY KEY
The problem that made me create this question is that I'm using H2, and I should try to create the migration scripts the most pure SQL compliant as Oracle allows me, and since GENERATED AS IDENTITY is pure SQL and it's now supported by Oracle DB, I should try to stick with that.
So, my first question is:
In H2, I can't follow this approach, as GENERATED AS IDENTITY will always implicitly create a PRIMARY KEY constraint, as pointed in H2 Database Documentation:
Identity and auto-increment columns are columns with a sequence as the default. The column declared as the identity columns is implicitly the primary key column of this table (unlike auto-increment columns).
So for H2, I need to use AUTO_INCREMENT instead.
I looked for the documentation of Oracle DB and I didn't find any information about primary keys for the identity type, does it mean that Oracle's GENERATED AS IDENTITY work just as H2's AUTO_INCREMENT?
And if the answer is positive and GENERATED AS IDENTITY is different for each database, does anyone have any idea of how to use the same migration script for both databases, or is it impossible?
Thank you!
Yes, it is possible (Oracle 12c):
CREATE TABLE tab (
id INT PRIMARY KEY,
some_identity NUMBER GENERATED ALWAYS AS IDENTITY, -- it is not PK
descr VARCHAR2(30)
);
or with DEFAULT:
CREATE SEQUENCE seq;
CREATE TABLE tab(
id INT PRIMARY KEY
,some_identity NUMBER DEFAULT seq.NEXTVAL
,descr VARCHAR2(30)
);

SQL - Field Grouping and temporary data restructruing

I would like to apologize first about my title, because I understand it may be technically incorrect
I currently have a database with multiple tables, 4 of them are relevant in this example.
FORMS
FIELDS
ENTRIES
VALUES
Below is a shortened version of the tables
Create table Form_Master
(
form_id int identity primary key ,
form_name varchar(255) ,
form_description varchar(255),
form_create_date date ,
)
Create table Field_Master
(field_id int identity primary key,
form_ID int foreign key references Form_Master(form_id),
field_name varchar(255),
type_ID int
)
Create table Entry_Master
(
entry_id int identity primary key,
entry_date date,
form_id int foreign key references Form_Master(form_id),
)
Create table Value_Master
(
value_id int identity primary key,
value varchar(255),
field_id int foreign key references Field_Master(field_id),
entry_id int foreign key references Entry_Master(entry_id),
)
The purpose of these tables is to create a dynamic method of capturing and retrieving information - a form is a table, a field is a column, and entry is a row and a value is a cell
Currently when I am retrieving information from a form, I create a temporary table, with columns as such in the field_master, then select all entries linked to the form, and the values linked to those entries, and insert them into the temporary table I have just created.
The reason for the temporary table is to restructure the data into an organised format and display it in a DataGridView.
My problem is one of performance, creating the table as mentioned above is becoming slower as forms exceed fields > 20 or entries linked to a form exceeds > 100
My questions are:
Is there a way to select the data directly from field_master in the format of the temporary table mentioned above?
Do you think I should re-think my database design?
Is there an easier method to do what I am trying to do?
Any input will be appreciated, I do know how to use Google, however in this instance I am not sure what exactly to look for, so even a keyword would be nice.