Example SQL Database : Orders
The example database is Orders history database to show example DDL (Data Definition Language) and DML (Data Manipulation Language) capabilities
provided by SQLDatabase.Net library.
You can also download complete database with sample data and sql scripts. SQL Code is also below on this page.
Table Name |
Description |
Primary Key |
Customers |
Customers table with customer information |
CustomerId |
Suppliers |
Supplier information for each product, supplier id is used to identify supplier of product |
SupplierId |
Products |
Information about products such as name, price and supplier id and if any discount package controlled by front end. |
ProductId |
Orders |
Order information |
OrderId |
OrderItems |
Items in a particular order |
OrderItemId |
OrderAdditionalAmounts |
Any other amount to add or remove from final order price such as tax, shipping etc |
|
InvoiceNumbers |
Invoice generated from front end and stored on disk in pdf format |
Id |
SQL Create Statements
Following sql statements creates tables, indexes and triggers.
/* Drop the table only if it exists, another syntax is DROP TABLE Customers */
DROP TABLE IF EXISTS Customers;
/* Create table only if it does not exists, another syntax is CREATE TABLE Customers */
CREATE TABLE IF NOT EXISTS Customers (
CustomerId INTEGER PRIMARY KEY
,FirstName TEXT NOT NULL
,LastName TEXT NOT NULL
,City TEXT NULL
,Country TEXT NULL
,Phone TEXT NULL
,Email TEXT NULL
);
/* Index will be created on customers table on lastname and firstname column in ascending order another syntax is CREATE INDEX [index name] */
CREATE INDEX IF NOT EXISTS IdxCustomerName on Customers (LastName ASC, FirstName ASC);
DROP TABLE IF EXISTS Suppliers;
CREATE TABLE IF NOT EXISTS Suppliers (
SupplierId INTEGER PRIMARY KEY,
CompanyName TEXT NOT NULL,
ContactName TEXT NULL,
ContactTitle TEXT NULL,
City TEXT NULL,
Country TEXT NULL,
Phone TEXT NULL,
Email TEXT NULL
);
/* Indexes will be created on suppliers table, keyword ASC or DESC are not required. */
CREATE INDEX IF NOT EXISTS IdxSupplierName on Suppliers (CompanyName ASC);
CREATE INDEX IF NOT EXISTS IdxSupplierCountry on Suppliers (Country ASC);
CREATE TRIGGER ValidateEmailBeforeInsert_Suppliers BEFORE INSERT ON Suppliers
BEGIN
SELECT
CASE
WHEN NEW.email NOT LIKE '%_@__%._%' THEN
RAISE ( ABORT, 'Invalid email address' )
END;
END;
DROP TABLE IF EXISTS Products;
CREATE TABLE IF NOT EXISTS Products (
ProductId INTEGER PRIMARY KEY
,ProductName TEXT NOT NULL
,SupplierId INTEGER NOT NULL DEFAULT 0 REFERENCES Suppliers(SupplierId)
,UnitPrice REAL NULL DEFAULT 0.00
,Package TEXT NULL
,IsDiscontinued INTEGER NOT NULL CHECK (IsDiscontinued IN (1, 0))
);
CREATE INDEX IF NOT EXISTS IdxProductSupplierId on Products (SupplierId ASC);
CREATE INDEX IF NOT EXISTS IdxProductName on Products (ProductName ASC);
DROP TABLE IF EXISTS Orders;
CREATE TABLE IF NOT EXISTS Orders (
OrderId INTEGER PRIMARY KEY,
OrderDate TEXT NOT NULL,
OrderNumber TEXT NULL,
CustomerId INTEGER NOT NULL REFERENCES Customers(CustomerId),
TotalAmount REAL NULL DEFAULT 0.00
);
CREATE INDEX IF NOT EXISTS IdxOrderCustomerId on Orders (CustomerId ASC);
CREATE INDEX IF NOT EXISTS IdxOrderOrderDate on Orders (OrderDate ASC);
DROP TABLE IF EXISTS OrderItems;
CREATE TABLE IF NOT EXISTS OrderItems (
OrderItemId INTEGER PRIMARY KEY,
OrderId INTEGER NOT NULL REFERENCES Orders(OrderId) ON UPDATE CASCADE ON DELETE CASCADE,
ProductId INTEGER NOT NULL REFERENCES Products(ProductId),
UnitPrice REAL NOT NULL DEFAULT 0.00,
Quantity INTEGER NOT NULL DEFAULT 1,
UNIQUE (OrderId, ProductId) ON CONFLICT ABORT
);
CREATE INDEX IF NOT EXISTS IdxOrderItemOrderId on OrderItems (OrderId ASC);
CREATE INDEX IF NOT EXISTS IdxOrderItemProductId on OrderItems (ProductId ASC);
DROP TABLE IF EXISTS OrderAdditionalAmounts;
CREATE TABLE IF NOT EXISTS OrderAdditionalAmounts (
AdditionId INTEGER PRIMARY KEY
,OrderId INTEGER NOT NULL
,Addition TEXT NOT NULL
,AddOrRemove TEXT NOT NULL
,AmountOrValue REAL NULL DEFAULT 0.00
,IsPercentage INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS IdxOrderCustomerId on Orders (CustomerId ASC);
CREATE INDEX IF NOT EXISTS IdxOrderOrderDate on Orders (OrderDate ASC);
/* Table with Auto increment column as primary key */
DROP TABLE IF EXISTS InvoiceNumbers;
CREATE TABLE IF NOT EXISTS InvoiceNumbers (
Id INTEGER PRIMARY KEY AUTOINCREMENT
,PDFFilePath TEXT NOT NULL
);
View Name |
Description |
vw_CustomerOrders |
Customer orders, views joins Customers and Orders table to produce desired rows and columns. |
vw_Top10CustomersByOrders |
Top 10 customers by total number of orders. |
vw_Top10CustomersByOrderAmount |
View joins Customers and Orders table find top 10 customers by Order total. |
SQL Code to Create Views
Views are similar to tables but they are based on either one or more tables or existing views, they can use indexes if the underlying table has indexes and such index is useable in the query used to
create that particular view. The sql database library only support read only views. All SELECT operations can be performed against a view they are like "Virtual Tables" in the database.
CREATE VIEW IF NOT EXISTS vw_CustomerOrders
AS
SELECT c.CustomerId, c.FirstName, c.LastName, o.OrderId, o.OrderNumber
, DateTimeFormat(o.OrderDate, 'yyyy-MM-dd', 'en-US') AS OrderDate
, FormatCurrency(o.TotalAmount) AS TotalAmount
FROM Customers c JOIN Orders o ON c.CustomerId = o.CustomerId
ORDER BY c.CustomerId;
/* View using another view as table */
CREATE VIEW IF NOT EXISTS vw_Top10CustomersByOrders
AS
SELECT v.CustomerId, v.FirstName, v.LastName
, COUNT(v.CustomerId) As TotalOrders
, FormatCurrency(Sum(substr(TotalAmount,2))) AS OrdersTotal
FROM vw_CustomerOrders v
GROUP BY CustomerId
ORDER BY TotalOrders DESC
LIMIT 10 OFFSET 0 ;
/* View similar to top 10 customers by orders but using table */
CREATE VIEW IF NOT EXISTS vw_Top10CustomersByOrderAmount
AS
SELECT c.CustomerId, c.FirstName, c.LastName
, COUNT(o.CustomerId) AS TotalOrders
, FormatCurrency(Sum(o.TotalAmount)) AS OrdersTotal
FROM Customers c JOIN Orders o ON c.CustomerId = o.CustomerId
GROUP BY c.CustomerId HAVING COUNT(o.CustomerId) > 0
Order By OrdersTotal DESC
LIMIT 10 OFFSET 0 ;
Trigger Name |
Description |
ValidateEmailBeforeInsert_Suppliers |
Validates email address before insert. |
Create Triggers
The following sql code is to create a trigger and can also be found above with tables and index statements.
CREATE TRIGGER ValidateEmailBeforeInsert_Suppliers BEFORE INSERT ON Suppliers
BEGIN
SELECT
CASE
WHEN NEW.email NOT LIKE '%_@__%._%' THEN
RAISE ( ABORT, 'Invalid email address' )
END;
END;