user defined data types allowed in testing views? - tsqlt

I'm using tsqlt to test a view -- OrderHeader, which joins OrderHeader with OrderState. In a set up procedure I create fake tables for those two tables, and insert rows. The table defs and user defined data types are below.
When I run the tsqt procedure I've written to test the views, I create an expected table
CREATE TABLE expected_v_ctOrderHeader
(
[countOrderNumber] dbo.orderNumber NOT NULL
,[orderId] dbo.id NOT NULL
,[orderType] dbo.orderType NOT NULL
,[orderClass] dbo.orderClass NOT NULL
,[orderState] dbo.orderState NOT NULL
,[site] dbo.site NOT NULL
,[region] [dbo].[region] NULL
,[currentInstance] INT NOT NULL
,[prOrderId] [dbo].[id] NULL
,[description] dbo.description NULL
,[isSoftCount] BIT NOT NULL
,[dtDue] DATETIMEOFFSET NULL
,[orderMethod] [dbo].[orderMethod] NOT NULL
,[availableForCounting] BIT NOT NULL
);
Insert into it the same data as in the SetUp procedure:
INSERT INTO dbo.expected_v_ctOrderHeader
(
[countOrderNumber]
,[orderId]
,[orderType]
,[orderClass]
,[orderState]
,[site]
,[region]
,[currentInstance]
,[prOrderId]
,[description]
,[isSoftCount]
,[dtDue]
,[orderMethod]
,[availableForCounting]
)
VALUES
('10'
,'10'
,'10'
,'10'
,'10'
,'10'
,'10'
,'10'
,'10'
,'10'
,'1'
,'1/1/2020'
,'10'
,'1')
,('100'
,'100'
,'100'
,'100'
,'100'
,'100'
,'100'
,'100'
,'100'
,'100'
,'1'
,'2/1/2020'
,'100'
,'0')
,('200'
,'200'
,'200'
,'200'
,'200'
,'200'
,'200'
,'200'
,'200'
,'200'
,'0'
,'3/1/2020'
,'200'
,'1')
Do an EXEC tsqlt.AssertEqualsTable
EXEC tSQLt.AssertEqualsTable
#Expected = N'dbo.expected_v_ctOrderHeader'
, #Actual = N'dbo.v_ctOrderHeader'
The base tables are defined using user defined types as follows:
The UDTs are as follows:
[dbo].[orderNumber] VARCHAR(50)
[dbo].[id] INT
[dbo].[orderType] NVARCHAR(50)
[dbo].[orderClass] NVARCHAR(50)
[dbo].[orderState] NVARCHAR(50)
[dbo].[site] VARCHAR(50)
[dbo].[region] VARCHAR(50)
[dbo].[description] NVARCHAR(500)
[dbo].[orderMethod] NVARCHAR(50)
The view definition is:
SELECT ch.[countOrderNumber] --[dbo].[orderNumber]
,ch.[orderId] --[dbo].[id]
,ch.[orderType] --[dbo].[orderType]
,ch.[orderClass] --[dbo].[orderClass]
,ch.[orderState] --[dbo].[orderState]
,ch.[site] --[dbo].[site]
,ch.[region] --[dbo].[region]
,ch.[instance] AS currentInstance --INT
,ch.[prOrderId] --[dbo].[id]
,ch.[description] --[dbo].[description]
,ch.[isSoftCount] --BIT
,ch.[dtDue] --DATETIMEOFFSET
,ch.[orderMethod] --[dbo].[orderMethod]
,cs.[availableForCounting]--BIT
FROM [dbo].[ctOrderHeader] ch
INNER JOIN [dbo].[ctOrderState] cs ON ch.orderState = cs.orderState
--tsql
CREATE TABLE [dbo].[ctOrderHeader](
[countOrderNumber] [dbo].[orderNumber] NOT NULL,
[orderId] [dbo].[id] NOT NULL,
[orderType] [dbo].[orderType] NOT NULL,
[orderClass] [dbo].[orderClass] NOT NULL,
[orderState] [dbo].[orderState] NOT NULL,
[site] [dbo].[site] NOT NULL,
[region] [dbo].[region] NULL,
[instance] [int] NOT NULL,
[prOrderId] [dbo].[id] NULL,
[description] [dbo].[description] NULL,
[isSoftCount] [bit] NOT NULL,
[dtDue] [datetimeoffset](7) NULL,
[orderMethod] [dbo].[orderMethod] NOT NULL,
CONSTRAINT [PK_ctOrderHeader_countOrderNumber] PRIMARY KEY CLUSTERED
(
[countOrderNumber] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [UQ_ctOrderHeader_countOrderNumber] UNIQUE NONCLUSTERED
(
[countOrderNumber] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[ctOrderState](
[orderState] [dbo].[orderState] NOT NULL,
[description] [dbo].[description] NOT NULL,
[displayName] [dbo].[displayName] NOT NULL,
[availableForCounting] [bit] NOT NULL,
CONSTRAINT [PK_ctOrderState_orderState] PRIMARY KEY CLUSTERED
(
[orderState] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
--
The tsql test fails (it should pass), with the following message:
(1 row affected)
[v_ctOrderHeader].[Test Data] failed: (Failure) Unexpected/missing column(s)
One example 'missing' column is
|< countOrderNumber, with a system_type_id AND user_type_id as VARCHAR(50)
The actual countOrderNumber is system_type_id = VARCHAR(50) and user_type_id = dbo.orderNumber.
I have tried all permutations for creating the expected table (using the UDT, or not) and always get the same error.
I have also tried inserting into a temp table the results of the view:
SELECT * INTO #t FROM v_ctOrderHeader
EXEC tSQLt.AssertEqualsTable
#Expected = N'dbo.expected_v_ctOrderHeader' -- nvarchar(max)
, #Actual = #t
And get the identical errors (mismatches).

Have you tried creating both the actual and expected tables via SELECT .. INTO?
This will create both tables with exactly the same format and remove the column difference. Use TOP(0) for the expected table. An example test is:
CREATE OR ALTER PROC v_ctOrderHeader.[Test Data]
AS
--arrange
SELECT TOP (0)
*
INTO v_ctOrderHeader.Expected
FROM dbo.YourViewName;
--populate v_ctOrderHeader.Expected
EXEC tSQLt.FakeTable #TableName = N'dbo.ctOrderHeader';
EXEC tSQLt.FakeTable #TableName = N'dbo.ctOrderState';
--populate dbo.ctOrderHeader
--populate dbo.ctOrderState
--act
SELECT *
INTO v_ctOrderHeader.Actual
FROM dbo.YourViewName;
--assert
EXEC tSQLt.AssertEqualsTable #Expected = N'v_ctOrderHeader.Expected', -- nvarchar(max)
#Actual = N'v_ctOrderHeader.Actual', -- nvarchar(max)
#Message = N'', -- nvarchar(max)
#FailMsg = N''; -- nvarchar(max)

I am unable to recreate the problems you are seeing and am able to run th test you have provided without error, i.e. it passes as expected.
For reference, I am running SQL2017 and tSQLt 1.0.5873.27393.
This is my code (all in one block for ease):
--!
--! Create base objects
--!
CREATE TYPE [dbo].[orderNumber] FROM varchar(50) ;
CREATE TYPE [dbo].[id] FROM int ;
CREATE TYPE [dbo].[orderType] FROM nvarchar(50) ;
CREATE TYPE [dbo].[orderClass] FROM nvarchar(50) ;
CREATE TYPE [dbo].[orderState] FROM nvarchar(50) ;
CREATE TYPE [dbo].[site] FROM varchar(50) ;
CREATE TYPE [dbo].[region] FROM varchar(50) ;
CREATE TYPE [dbo].[description] FROM nvarchar(500) ;
CREATE TYPE [dbo].[orderMethod] FROM nvarchar(50) ;
CREATE TYPE [dbo].[displayName] FROM nvarchar(128) ;
GO
CREATE TABLE [dbo].[ctOrderState](
[orderState] [dbo].[orderState] NOT NULL,
[description] [dbo].[description] NOT NULL,
[displayName] [dbo].[displayName] NOT NULL,
[availableForCounting] [bit] NOT NULL,
CONSTRAINT [PK_ctOrderState_orderState] PRIMARY KEY CLUSTERED
(
[orderState] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[ctOrderHeader](
[countOrderNumber] [dbo].[orderNumber] NOT NULL,
[orderId] [dbo].[id] NOT NULL,
[orderType] [dbo].[orderType] NOT NULL,
[orderClass] [dbo].[orderClass] NOT NULL,
[orderState] [dbo].[orderState] NOT NULL,
[site] [dbo].[site] NOT NULL,
[region] [dbo].[region] NULL,
[instance] [int] NOT NULL,
[prOrderId] [dbo].[id] NULL,
[description] [dbo].[description] NULL,
[isSoftCount] [bit] NOT NULL,
[dtDue] [datetimeoffset](7) NULL,
[orderMethod] [dbo].[orderMethod] NOT NULL,
CONSTRAINT [PK_ctOrderHeader_countOrderNumber] PRIMARY KEY CLUSTERED
(
[countOrderNumber] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [UQ_ctOrderHeader_countOrderNumber] UNIQUE NONCLUSTERED
(
[countOrderNumber] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
IF OBJECTPROPERTYEX(OBJECT_ID(N'[dbo].[v_ctOrderHeader]'), N'IsView') = 1
DROP VIEW [dbo].[v_ctOrderHeader]
GO
CREATE OR ALTER VIEW [dbo].[v_ctOrderHeader]
AS
SELECT ch.[countOrderNumber] --[dbo].[orderNumber]
,ch.[orderId] --[dbo].[id]
,ch.[orderType] --[dbo].[orderType]
,ch.[orderClass] --[dbo].[orderClass]
,ch.[orderState] --[dbo].[orderState]
,ch.[site] --[dbo].[site]
,ch.[region] --[dbo].[region]
,ch.[instance] AS currentInstance --INT
,ch.[prOrderId] --[dbo].[id]
,ch.[description] --[dbo].[description]
,ch.[isSoftCount] --BIT
,ch.[dtDue] --DATETIMEOFFSET
,ch.[orderMethod] --[dbo].[orderMethod]
,cs.[availableForCounting]--BIT
FROM [dbo].[ctOrderHeader] ch
INNER JOIN [dbo].[ctOrderState] cs ON ch.orderState = cs.orderState
GO
--!
--! Create test objects
--!
EXEC tSQLt.NewTestClass #ClassName = N'StackOverflowTests';
GO
IF OBJECTPROPERTYEX(OBJECT_ID(N'[StackOverflowTests].[SetUp]'), N'IsProcedure') = 1
DROP PROCEDURE [StackOverflowTests].[SetUp]
GO
CREATE PROCEDURE [StackOverflowTests].[SetUp]
AS
BEGIN
EXEC tSQLt.FakeTable #TableName = N'dbo.ctOrderState' ;
EXEC tSQLt.FakeTable #TableName = N'dbo.ctOrderHeader' ;
INSERT dbo.ctOrderState (orderState, [description] , displayName, availableForCounting)
VALUES (10, 'Not Specified 10', 'Number 10', 1 )
, (100, 'Not Specified 100', 'Number 100', 1 )
, (200, 'Not Specified 200', 'Number 200', 1 )
;
INSERT dbo.ctOrderHeader
(
countOrderNumber
, orderId
, orderType
, orderClass
, orderState
, site
, region
, instance
, prOrderId
, description
, isSoftCount
, dtDue
, orderMethod
)
VALUES
(
'10' -- countOrderNumber - orderNumber
, 10 -- orderId - id
, '10' -- orderType - orderType
, '10' -- orderClass - orderClass
, '10' -- orderState - orderState
, '10' -- site - site
, '10' -- region - region
, 10 -- instance - int
, 10 -- prOrderId - id
, '10' -- description - description
, 1 -- isSoftCount - bit
, '20200101' -- dtDue - datetimeoffset(7)
, '10' -- orderMethod - orderMethod
)
, (
'100' -- countOrderNumber - orderNumber
, 100 -- orderId - id
, '100' -- orderType - orderType
, '100' -- orderClass - orderClass
, '100' -- orderState - orderState
, '100' -- site - site
, '100' -- region - region
, 100 -- instance - int
, 100 -- prOrderId - id
, '100' -- description - description
, 1 -- isSoftCount - bit
, '20200102' -- dtDue - datetimeoffset(7)
, '100' -- orderMethod - orderMethod
)
, (
'200' -- countOrderNumber - orderNumber
, 200 -- orderId - id
, '200' -- orderType - orderType
, '200' -- orderClass - orderClass
, '200' -- orderState - orderState
, '200' -- site - site
, '200' -- region - region
, 200 -- instance - int
, 200 -- prOrderId - id
, '200' -- description - description
, 0 -- isSoftCount - bit
, '20200103' -- dtDue - datetimeoffset(7)
, '200' -- orderMethod - orderMethod
)
;
END
GO
IF OBJECTPROPERTYEX(OBJECT_ID(N'[StackOverflowTests].[test v_ctOrderHeader join conditione]'), N'IsProcedure') = 1
DROP PROCEDURE [StackOverflowTests].[test v_ctOrderHeader join condition]
GO
CREATE OR ALTER PROCEDURE [StackOverflowTests].[test v_ctOrderHeader join condition]
AS
BEGIN
CREATE TABLE expected_v_ctOrderHeader
(
[countOrderNumber] dbo.orderNumber NOT NULL
,[orderId] dbo.id NOT NULL
,[orderType] dbo.orderType NOT NULL
,[orderClass] dbo.orderClass NOT NULL
,[orderState] dbo.orderState NOT NULL
,[site] dbo.site NOT NULL
,[region] [dbo].[region] NULL
,[currentInstance] INT NOT NULL
,[prOrderId] [dbo].[id] NULL
,[description] dbo.description NULL
,[isSoftCount] BIT NOT NULL
,[dtDue] DATETIMEOFFSET NULL
,[orderMethod] [dbo].[orderMethod] NOT NULL
,[availableForCounting] BIT NOT NULL
);
-- INSERT into it the same data as in the SetUp procedure:
INSERT INTO dbo.expected_v_ctOrderHeader
(
[countOrderNumber]
,[orderId]
,[orderType]
,[orderClass]
,[orderState]
,[site]
,[region]
,[currentInstance]
,[prOrderId]
,[description]
,[isSoftCount]
,[dtDue]
,[orderMethod]
,[availableForCounting]
)
VALUES
('10'
,'10'
,'10'
,'10'
,'10'
,'10'
,'10'
,'10'
,'10'
,'10'
,'1'
,'20200101'
,'10'
,'1')
,('100'
,'100'
,'100'
,'100'
,'100'
,'100'
,'100'
,'100'
,'100'
,'100'
,'1'
,'20200102'
,'100'
,'1')
,('200'
,'200'
,'200'
,'200'
,'200'
,'200'
,'200'
,'200'
,'200'
,'200'
,'0'
,'20200103'
,'200'
,'1');
EXEC tSQLt.AssertEqualsTable
#Expected = N'dbo.expected_v_ctOrderHeader'
, #Actual = N'dbo.v_ctOrderHeader'
END
GO
--!
--! Run the tests
--!
EXEC tSQLt.Run 'StackOverflowTests';
GO
And this is the result I get:
+----------------------+
|Test Execution Summary|
+----------------------+
|No|Test Case Name |Dur(ms)|Result |
+--+----------------------------------------------------------+-------+-------+
|1 |[StackOverflowTests].[test v_ctOrderHeader join condition]| 47|Success|
-----------------------------------------------------------------------------
Test Case Summary: 1 test case(s) executed, 1 succeeded, 0 failed, 0 errored.
-----------------------------------------------------------------------------
Are you doing anything different in your test or setup than I am doing above? Maybe an older version of tSQLt?
Hope this helps

Related

Insert Data into SQL Table with primary key column

I have a table in a SQL Server database and an R script that appends data to that tabl.
The db table contains a primary key ("ID"), which is just a scope_identity field
When I try to append the table into that location, I keep running into the following error
> sqlSave(Conn[["DbCon"]],
+ dat = OutputDataFinal,
+ tablename = "DataSci_StandardTransferPriority",
+ verbose = TRUE,
+ append = TRUE,
+ rownames = FALSE)
Query:
INSERT INTO "DataSci_StandardTransferPriority" (
"ID", "LeadSourceName", "AgeCategory", "ZipColor", "LeadCount_Sum",
"OB_TotalDials_Sum", "ContactRate", "TransferRate", "HypTransfers", "LaborCPT",
"MarketingCpt", "CloseRate", "PDLTR", "Policy_Count_Sum", "InboundDials_Sum",
"LeadCost_Sum", "PPT", "PPH", "ContactRateXCloseRate", "ContactRateXCloseRateTarget",
"ModelValue", "SourcePriority", "InsertTS"
)
VALUES ( ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? )
Error in odbcUpdate(channel, query, mydata, coldata[m, ], test = test, :
missing columns in 'data'
How can I append and ignore the issue with the primary key?
In standard INSERT operation dont specify identity column. It automatically provides next incremental identity value. For example:
CREATE TABLE #TempTable (
[ID] [bigint] NOT NULL IDENTITY(1, 1) PRIMARY KEY,
[Column1] [varchar](50) NULL,
[Column2] [decimal](19, 3) NOT NULL
);
INSERT INTO #TempTable (
[Column1],
[Column2]
)
VALUES
('first insert', 50.2),
('second insert', 84.2);
SELECT *
FROM #TempTable
DROP TABLE #TempTable;
The result was:
ID
Column1
Column2
1
first insert
50.200
2
second insert
84.200
If you want insert on identity column any way - enable IDENTITY_INSERT. But be care for data integrity issues.
CREATE TABLE #TempTable (
[ID] [bigint] NOT NULL IDENTITY(1, 1) PRIMARY KEY,
[Column1] [varchar](50) NULL,
[Column2] [decimal](19, 3) NOT NULL
);
INSERT INTO #TempTable (
[Column1],
[Column2]
)
VALUES ('first insert', 50.2);
SET IDENTITY_INSERT #TempTable ON;
INSERT INTO #TempTable (
[ID],
[Column1],
[Column2]
)
VALUES
(4, 'second insert', 84.63),
(2, 'third insert', 99.56);
SET IDENTITY_INSERT #TempTable OFF;
INSERT INTO #TempTable (
[Column1],
[Column2]
)
VALUES ('four insert', 100.32);
SELECT *
FROM #TempTable
DROP TABLE #TempTable;
And the result:
ID
Column1
Column2
1
first insert
50.200
2
third insert
99.560
4
second insert
84.630
5
four insert
100.320

MariaDB limit value of column

I want to limit the value of the column limited_column, where 0 >= limited_column <= 100 SQL side, on MariaDB
I've tried creating a trigger on INSERT ad UPDATE as such:
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`username` varchar(25) NOT NULL,
`user_id` int(100) NOT NULL,
`limited_column` bigint(20) unsigned NOT NULL DEFAULT '0',
[...]
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
DELIMITER $$
CREATE TRIGGER `limited_column_check_on_insert_trigger` BEFORE INSERT ON `users` FOR EACH ROW
BEGIN
DECLARE dummy,baddataflag INT;
SET baddataflag = 0;
IF NEW.limited_column > 100 THEN
SET baddataflag = 1;
END IF;
IF NEW.limited_column < 0 THEN
SET baddataflag = 1;
END IF;
IF baddataflag = 1 THEN
SELECT CONCAT('Cannot INSERT new value because limited_column is > 100, value was ',NEW.limited_column)
INTO dummy FROM information_schema.tables;
END IF;
END; $$
CREATE TRIGGER `limited_column_check_on_update_trigger` BEFORE UPDATE ON `users` FOR EACH ROW
BEGIN
DECLARE dummy,baddataflag INT;
SET baddataflag = 0;
IF NEW.limited_column > 100 THEN
SET baddataflag = 1;
END IF;
IF NEW.limited_column < 0 THEN
SET baddataflag = 1;
END IF;
IF baddataflag = 1 THEN
SELECT CONCAT('Cannot UPDATE new value because limited_column is > 100, value was ',NEW.limited_column)
INTO dummy FROM information_schema.tables;
END IF;
END; $$
DELIMITER ;
This is what I get if I try inserting a new user when limited_column > 100 (limited_column > 100 works):
MariaDB [NameOfADatabase]> INSERT INTO users (username,user_id,limited_column,[...]) VALUES ('testestes',1,1000,[...]);
ERROR 1172 (42000): Result consisted of more than one row
MariaDB [NameOfADatabase]> INSERT INTO users (username,user_id,limited_column,[...]) VALUES ('testestes',2,100,[...]);
Query OK, 1 row affected (0.02 sec)
Any ideas on what I can do to make this more graceful?
This is running on 10.1.38-MariaDB-0ubuntu0.18.04.2 Ubuntu 18.04
Upgrading to 10.3.15 was the best solution for this, as I can use the CHECK option. Thanks to #RickJames for the info about the update.
Here's the Schema I'm using that works:
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`username` varchar(25) NOT NULL,
`user_id` int(100) NOT NULL,
`limited_column` bigint(20) unsigned NOT NULL DEFAULT '0',
[...]
PRIMARY KEY (`user_id`),
CHECK (limited_column<=100)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Here's the output I get:
MariaDB [NameOfADatabase]> INSERT INTO users (username,user_id,limited_column,[...]) VALUES ('test1',1,100,[...]);
Query OK, 1 row affected (0.016 sec)
MariaDB [NameOfADatabase]> INSERT INTO users (username,user_id,limited_column,[...]) VALUES ('test2',2,101,[...]);
ERROR 4025 (23000): CONSTRAINT `CONSTRAINT_1` failed for `NameOfADatabase`.`users`

Getting error :Error(2,3): PL/SQL: SQL Statement ignored Error(8,5): PL/SQL: ORA-00984: column not allowed here

My code is like below.
create table XXINF_DB_OBJECT_DDL_LOG (
EVENT_DATE DATE NOT NULL,
EVENT_TIMESTAMP TIMESTAMP NOT NULL,
EVENT_TYPE VARCHAR2(30) NOT NULL,
OBJECT_TYPE VARCHAR2(30) NOT NULL,
OBJECT_OWNER VARCHAR2(30) NOT NULL,
OBJECT_NAME VARCHAR2(30) NOT NULL,
DB_USER VARCHAR2(30) NOT NULL,
OS_USER VARCHAR2(100) ,
HOST_NAME VARCHAR2(100),
HOST_IP_ADDRESS VARCHAR2(30)
);
create or replace trigger XXINF_DB_OBJECT_DDL_LOG_AUDIT
AFTER DDL ON schema
begin
insert into XXINF_DB_OBJECT_DDL_LOG values(
sysdate,
systimestamp,
ora_sysevent,
ora_dict_obj_type,
ora_dict_obj_owner,
ora_dict_odj_name,
ora_login_user,
SYS_CONTEXT('USERENV','OS_USER'),
SYS_CONTEXT('USERENV','TERMINAL'),
SYS_CONTEXT('USERENV','IP_ADDRESS')
);
END;
/
when I execute get error:
Error(2,3): PL/SQL: SQL Statement ignored Error(8,5): PL/SQL:
ORA-00984: column not allowed here
Please use the corrections as below:
create or replace trigger XXINF_DB_OBJECT_DDL_LOG_AUDIT
AFTER DDL ON SCHEMA
begin
insert into XXINF_DB_OBJECT_DDL_LOG
(
EVENT_DATE,
EVENT_TIMESTAMP,
EVENT_TYPE,
OBJECT_TYPE,
OBJECT_OWNER,
OBJECT_NAME,
DB_USER,
OS_USER,
HOST_NAME,
HOST_IP_ADDRESS
)
values
(
sysdate,
systimestamp,
ora_sysevent,
ora_dict_obj_type ,
ora_dict_obj_owner,
ora_dict_obj_name ,
ora_login_user ,
SYS_CONTEXT('USERENV','OS_USER'),
SYS_CONTEXT('USERENV','TERMINAL'),
SYS_CONTEXT('USERENV','IP_ADDRESS') );
END;
/

Identity column

Stored Procedure
CREATE PROCEDURE [dbo].[Insert_Customer]
#id int,
#FName varchar(50) ,
#MName varchar(50) ,
#LName varchar(50) ,
#Age int ,
#Citizen varchar(50),
#Gender varchar(50) ,
#DOB varchar(50) ,
#Status varchar(50) ,
#Nationality varchar(50) ,
#Country varchar(50) ,
#State varchar(50) ,
#City varchar(50) ,
#Address varchar(MAX) ,
#Pin varchar(50) ,
#AccNo int IDENTITY (100,1),
#Branch varchar(50) ,
#IDProof varchar(50) ,
#IDNo varchar(50) ,
#IDName varchar(50) ,
#DOI varchar(50) ,
#Date datetime
AS
BEGIN
Insert into tbl_Customer1
values(#id,#FName,#MName,#LName,#Age,#Citizen,#Gender,#DOB,#Status,#Nationality)
Insert into tbl_Customer2
values(#id,#Country,#State,#City,#Address,#Pin,#accno ,#Branch)
Insert into tbl_Customer3
values(#id,#IDProof,#IDNo,#IDName,#DOI,#Date)
END
Here the error is
Msg 156, Level 15, State 1, Procedure Insert_Customer, Line 28
Incorrect syntax near the keyword 'IDENTITY'.
Msg 137, Level 15, State 2, Procedure Insert_Customer, Line 42
Must declare the scalar variable "#accno".
Msg 137, Level 15, State 2, Procedure Insert_Customer, Line 44
Must declare the scalar variable "#IDProof".
You cannot declare INT IDENTITY variable / parameter. If particular column defined as IDENTITY column, you don't have to add it's value insert statement. If you don't specify column value, identity number automatically will set.
#AccNo int IDENTITY (100,1),
you cant set a parameter as identity.
Why do you need it in the first place?
This should be only on your table.
Can you explain why do you need it so we can help you?

How to come up with statistics that shows the total number of quizzes, total number of participants?

I am developing a simple web application that provides the users with quizzes. since I am new to ASP.NET world, I am following the How to build Quiz Engine Video series on ASP.net website. My database design is to similar to the design used in these videos.
This is the link of the first video:
Everything works fine with me, but I want now to develop a query that helps me to display a statistics to the Admin which shows:
Total number of quizzes in the system
Total number of participants in each quiz
Total number of participants in general in daily basis, weekly basis, monthly basis and yearly basis (if possible)
To clarify the last point, I want the admin to see the following:
total number of participant druing last week was: ......
total number of taken quizzes during last week was: .........
total number of taken quizzes during last month was: .........
I think something like this is very useful to know the usage of the system and to show the management how the system is efficient in the copmany.
The sechma of the database:
CREATE TABLE [dbo].[Quiz](
[QuizID] [int] IDENTITY(1,1) NOT NULL,
[Title] [varchar](max) NOT NULL,
[Description] [varchar](max) NULL,
CONSTRAINT [PK_Quiz] PRIMARY KEY CLUSTERED
(
[QuizID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[Quiz] ON
INSERT [dbo].[Quiz] ([QuizID], [Title], [Description]) VALUES (6, N'Safety', N'General Safety Test')
INSERT [dbo].[Quiz] ([QuizID], [Title], [Description]) VALUES (7, N'my title', N'my description')
INSERT [dbo].[Quiz] ([QuizID], [Title], [Description]) VALUES (9, N'General Safety Quiz2', N'Testing')
INSERT [dbo].[Quiz] ([QuizID], [Title], [Description]) VALUES (10, N'General Safety Quiz3', N'Testing #2')
SET IDENTITY_INSERT [dbo].[Quiz] OFF
/****** Object: Table [dbo].[Question] Script Date: 11/17/2011 00:44:38 ******/
CREATE TABLE [dbo].[Question](
[QuestionID] [int] IDENTITY(1,1) NOT NULL,
[Question] [varchar](max) NOT NULL,
[Answer1] [varchar](max) NOT NULL,
[Answer2] [varchar](max) NOT NULL,
[Answer3] [varchar](max) NOT NULL,
[Answer4] [varchar](max) NOT NULL,
[CorrectAnswer] [tinyint] NOT NULL,
[AnswerExplanation] [varchar](max) NULL,
[QuestionOrder] [tinyint] NOT NULL,
[QuizID] [int] NOT NULL,
CONSTRAINT [PK_Question] PRIMARY KEY CLUSTERED
(
[QuestionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[Question] ON
INSERT [dbo].[Question] ([QuestionID], [Question], [Answer1], [Answer2], [Answer3], [Answer4], [CorrectAnswer], [AnswerExplanation], [QuestionOrder], [QuizID]) VALUES (4, N'What is your name?', N'Mohammed ', N'Ali', N'Hassan', N'Husain', 1, N'My Name', 1, 6)
INSERT [dbo].[Question] ([QuestionID], [Question], [Answer1], [Answer2], [Answer3], [Answer4], [CorrectAnswer], [AnswerExplanation], [QuestionOrder], [QuizID]) VALUES (7, N'What is the definition of Safety?', N'Being Safe', N'Being in danger', N'Be careful', N'be careless', 1, N'Nothing', 1, 9)
INSERT [dbo].[Question] ([QuestionID], [Question], [Answer1], [Answer2], [Answer3], [Answer4], [CorrectAnswer], [AnswerExplanation], [QuestionOrder], [QuizID]) VALUES (8, N'What is the definition of Safety? ', N'Being Safe', N'Being Careless', N'Being Careful', N'Being in Dangerous', 1, N'Nothing to say', 1, 10)
SET IDENTITY_INSERT [dbo].[Question] OFF
/****** Object: Table [dbo].[UserQuiz] Script Date: 11/17/2011 00:44:38 ******/
CREATE TABLE [dbo].[UserQuiz](
[UserQuizID] [int] NULL,
[QuizID] [int] NOT NULL,
[DateTimeComplete] [smalldatetime] NOT NULL,
[Score] [tinyint] NOT NULL,
[Username] [nvarchar](256) NOT NULL
) ON [PRIMARY]
GO
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (NULL, 6, CAST(0x9F8F02D8 AS SmallDateTime), 100, N'SMP\ALMARHMS')
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (NULL, 6, CAST(0x9F8F02E3 AS SmallDateTime), 50, N'SMP\ALMARHMS')
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (NULL, 6, CAST(0x9F8F0333 AS SmallDateTime), 50, N'SMP\ALMARHMS')
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (NULL, 7, CAST(0x9F8F0335 AS SmallDateTime), 100, N'SMP\ALMARHMS')
By help from one of the guys here in this great community, I came up with one query that shows the number of participants in each quiz. This is the query:
SELECT Q.QuizID, Q.Title, COUNT(*) AS Users
FROM dbo.UserQuiz AS UQ
INNER JOIN dbo.Quiz AS Q ON Q.QuizID = UQ.QuizID
GROUP BY Q.QuizID, Q.Title
Now I need to modify it or to come up withe new query that gives me the above three points. How can I do that?
If you want to count for the last 7 days and the last 30 days, you could use something like this:
-- Count of Participants in the last 7 days
SELECT COUNT(DISTINCT Q.UserName)
FROM dbo.UserQuiz Q
WHERE DateTimeComplete >= DATEADD(dd, -7, DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0))
-- Count quizzes taken in the last 7 days
SELECT COUNT(Q.QuizID)
FROM dbo.UserQuiz Q
WHERE Q.DateTimeComplete >= DATEADD(dd, -7, DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0))
-- Count quizzes taken in the last 30 days
SELECT COUNT(Q.QuizID)
FROM dbo.UserQuiz Q
WHERE Q.DateTimeComplete >= DATEADD(dd, -30, DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0))
Note that if you want to count for calendar weeks and calendar months then you need to do a bit more work to filter the proper starting and ending date filters.
EDIT: Fixed the query syntax (1st answer posted without running it in SSMS) also I didn't notice at first that the UserQuiz.UserQuizID is nullable. This column is therefore not what I would have expected it to be.
EDIT #2: As per OP's request, these three statistics can also be retrieved in a single query using sub-selects. Sub-selects are necessary because of differences in either the filter criteria or the aggregations involved in counting each statistic (or both).
-- Combine three stats into one query using sub-selects...
SELECT
(SELECT COUNT(DISTINCT Q.UserName)
FROM dbo.UserQuiz Q
WHERE DateTimeComplete >= DATEADD(dd, -7, DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)))
as ParticipantsLast7Days,
(SELECT COUNT(Q.QuizID)
FROM dbo.UserQuiz Q
WHERE Q.DateTimeComplete >= DATEADD(dd, -7, DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)))
as QuizzesLast7Days,
(SELECT COUNT(Q.QuizID)
FROM dbo.UserQuiz Q
WHERE Q.DateTimeComplete >= DATEADD(dd, -30, DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)))
as QuizzesLast30Days

Resources