I have the following 2 tables, and the default classes generated from
bin/cake bake all clients
bin/cake bake all clients_address
When I try and add an address, setting the "client_id" to 1, I get the following error.
Error: SQLSTATE[HY000]: General error: 1364 Field 'client_id' doesn't have a default value
If you are using SQL keywords as table column names, you can enable identifier quoting for your database connection in config/app.php.
SQL Query:
INSERT INTO clients_address (address_line_1, address_line_2, address_line_3, town, county, postcode, email, tel, contact_name, default_address) VALUES (:c0, :c1, :c2, :c3, :c4, :c5, :c6, :c7, :c8, :c9)
Is there some extra code needed to get the client_id to be submitted?
CREATE TABLE `clients` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `clients_address` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`address_line_1` varchar(30) NOT NULL,
`address_line_2` varchar(30) NOT NULL,
`address_line_3` varchar(30) NOT NULL,
`town` varchar(30) NOT NULL,
`county` varchar(30) NOT NULL,
`postcode` varchar(8) NOT NULL,
`email` varchar(50) NOT NULL,
`tel` varchar(13) NOT NULL,
`contact_name` varchar(40) NOT NULL,
`client_id` int(11) NOT NULL,
`default_address` BOOLEAN NOT NULL DEFAULT 0,
FOREIGN KEY (client_id) REFERENCES clients(id),
PRIMARY KEY (`id`)
);
INSERT INTO `clients` (`id`, `name`) VALUES (1, 'First Client');
In your clients_address Table schema client_id int(11) NOT NULL, set. But when you insert a Address then you don't set value against client_id and client_id can't be NULL
Probably solutions
Set client_id in Address insert query
In your table schema client_id allow NULL or set a default value
You need to be sure that "client_id" is sent. Check with your Debug Kit bar on History, select the POST request, and then go to Sql log.
There must be a query like this:
INSERT INTO clients_address (
client_id, address, modified
)
VALUES
(
61, 'my address', "123..."
)
If not maybe something is wrong with your Form.
Your query must be something like this:
INSERT INTO clients_address (address_line_1, ..., contact_name, CLIENT_ID, default_address)
VALUES (:c0, :c1, :c2, :c3, :c4, :c5, :c6, :c7, :c8, :c9)
If you are adding addresses standalone (addresses controller add method), you must stipulate "client_id" manually on Form, or from a hidden field based on a parameter, with Cake bake it will make a list of Clients on Add and Edit methods.
If you are adding the address from Client Form as an association, on CakePHP docs are some good examples https://book.cakephp.org/3.0/en/views/helpers/form.html#creating-inputs-for-associated-data
Related
Create statement for my first table: 'users':
CREATE TABLE users
(
uid INT NOT NULL IDENTITY PRIMARY KEY,
firstName VARCHAR(50) NOT NULL,
lastName VARCHAR(50) NOT NULL,
middle VARCHAR(50) NOT NULL,
ssn VARCHAR(12) NOT NULL,
dob DATE NOT NULL,
phone VARCHAR(10) NOT NULL,
email VARCHAR(255) NOT NULL
)
Create statement for my second table: 'ds':
CREATE TABLE ds
(
dsu VARCHAR(50) NOT NULL,
dsp VARCHAR(50) NOT NULL,
dsImage VARCHAR(50) NOT NULL,
dsid INT NOT NULL,
Name nvarchar(50),
CONSTRAINT PK_dsid
PRIMARY KEY NONCLUSTERED (dsid),
CONSTRAINT FK_users_uid
FOREIGN KEY (dsid) REFERENCES users (uid)
ON DELETE CASCADE
ON UPDATE CASCADE
);
The first table's uid column will auto-increment with each new row I insert. I want to setup the ds table's dsid column value in each new row to automatically update to match the users table uid column value.
When I try to INSERT INTO values into the ds table:
INSERT INTO ds (dsu, dsp, dsImage)
VALUES ('john.smith', '1234567', 'Tiger')
I get the following error:
Msg 515, Level 16, State 2, Line 1
Cannot insert the value NULL into column 'dsid', table 'company.dbo.ds'; column does not allow nulls. INSERT fails.
So, I'm trying to figure out if I'm setting up the primary key and foreign key create statements correctly to achieve the desired result, and also why I'm getting the error, and if I'm even approaching this task/problem correctly.
Any help is greatly appreciated, thank you!
I have this table:
CREATE TABLE [dbo].[UserProfile]
(
[UserId] INT IDENTITY (1, 1) NOT NULL,
[UserName] NVARCHAR (MAX) NULL,
[Gender] CHAR (10) NULL,
[Vegetarian] BIT NULL,
[Diet] NVARCHAR (50) NULL,
[Email] NVARCHAR(50) NULL,
[Birthday] SMALLDATETIME NULL,
PRIMARY KEY CLUSTERED ([UserId] ASC)
);
and I cannot update the database if I set a column to NOT NULL, or uncheck the Allow Null checkbox in the design mode. VS returns this error:
An error occurred while the batch was being executed.
No other information is given. Someone please explain this to me. I want UserName, Gender, and Email as NOT NULL.
UPDATE: I found out where the problem is. The sample users of my program does not have any data, that's why when I set new columns to NOT NULL, errors occur.
Run this query to locate the erroneous rows:
SELECT * FROM [dbo].[UserProfile]
WHERE UserName is NULL OR Gender is NULL or Email is NULL
You will probably have to run an update such as this before changing each column:
UPDATE [dbo].[UserProfile]
SET Email = N' '
WHERE Email is NULL
Don't try to combine the updates for the columns - you will run the risk of overwriting correct column values.
I have a ASP MVC web application that is required to load a user extract each day from a file. The users in the database should be updated accordingly: deleted if not in source, updated if in source and target, and created if only in source. While doing this, certain rights should also automatically be given to the users. If there is any error, nothing should happen at all.
First I tried to do this with Entity Framework, but the SaveChanges call takes around two minutes to return, which is a lot for the relatively small amount of users (~140 000).
My idea now is to write a stored procedure that would do the updating. I would pass the list of new users as a parameter. The type of my temporary table:
CREATE TYPE [dbo].[TempUserType] AS TABLE
(
[Uid] NVARCHAR(80) NOT NULL PRIMARY KEY,
[GivenName] NVARCHAR(80) NOT NULL,
[FamilyName] NVARCHAR(80) NOT NULL,
[Email] NVARCHAR(256) NOT NULL,
[GiveRight1] BIT NOT NULL,
[GiveRight2] BIT NOT NULL,
[GiveRight3] BIT NOT NULL
)
The users:
CREATE TABLE [dbo].[User] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Uid] NVARCHAR (80) NOT NULL,
[GivenName] NVARCHAR (80) NOT NULL,
[FamilyName] NVARCHAR (80) NOT NULL,
[Email] NVARCHAR (256) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC),
UNIQUE NONCLUSTERED ([Uid] ASC)
);
The user roles:
CREATE TABLE [dbo].[UserRole] (
[UserId] INT NOT NULL,
[RoleId] INT NOT NULL,
CONSTRAINT [PK_UserRole] PRIMARY KEY CLUSTERED ([UserId] ASC, [RoleId] ASC),
CONSTRAINT [FK_UserRole_User] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User] ([Id]),
CONSTRAINT [FK_UserRole_Role] FOREIGN KEY ([RoleId]) REFERENCES [dbo].[Role] ([Id])
);
The procedure I am stuck writing:
CREATE PROCEDURE [dbo].[UpdateUsers]
#extractedUsers TempUserType READONLY
AS
BEGIN TRANSACTION
MERGE
[dbo].[User] AS trg
USING
#extractedUsers AS src
ON
(trg.[Uid] = src.[Uid])
WHEN MATCHED THEN
UPDATE SET
trg.GivenName = src.GivenName,
trg.FamilyName = src.FamilyName,
trg.Email = src.Email
WHEN NOT MATCHED BY TARGET THEN
INSERT
([Uid], GivenName, FamilyName, Email)
VALUES
(src.[Uid], src.GivenName, src.FamilyName, src.Email)
WHEN NOT MATCHED BY SOURCE THEN
DELETE;
COMMIT TRANSACTION
My question: is the use of a procedure with merge appropriate in this case to achieve the performance improvement over EF? How can I attribute roles according to the 3 boolean values that are in the source table?
Roles can be hadcoded, meaning I know that the Right1 corresponds to the RoleId 1, Right 2 to RoleId 2 and Right 3 to RoleId3.
After reading the question I want to leave an idea for the solution.
For me it makes more sense to have an IF / ELSE for calling the update or the insert, not using the merge since you need the UserId that you are updating/inserting to add it's role permissions.
You can check if UId exists and if so update the user details, if does not exists then create and keep the new Identity value.
In both cases, when having the user ID add the corresponding permissions according to the boolean values with IF statements.
Pseudo-code:
If UserId exists in UsersTable
Update
Store UserId
Else
Insert
Store created UserId (using the ##IDENTITY)
If bool1 add permission 1
If bool3 add permission 2
If bool3 add permission 3
i am using the following statement.
$users = $this->User->find('all');
But in the database there are only 174 rows. but the query is returning 200 rows.
When i out put the content i see that a lot of rows are repeated.
Any idea why this behavior in cakephp ?
Structure
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(255) NOT NULL,
`last_name` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`username` varchar(255) NOT NULL,
`password` varchar(40) NOT NULL,
`display_photo` varchar(255) DEFAULT NULL,
`subscription_plan_id` int(11) unsigned NOT NULL,
`company_id` int(11) NOT NULL,
`status` tinyint(2) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=177 ;
by trying to debug using this statment
echo $users = $this->User->find('count');
i get 200 itself.
Models: http://pastebin.com/p4bFPiUz
The query you are running does not nearly match the queries that CakePHP will actually execute. CakePHP will also perform all the required joins to get related data. So, this is not really a proper comparison that you are doing.
Some of your relations might return double results, like User -> CompanyA, but there could also be a User -> CompanyB relation, which would trigger 2 result rows for 1 single user.
To see the queries that Cake actually executes, use the getLog method on your datasource, like:
$ds = $this->User->getDataSource();
$log = $ds->getLog();
debug($log);
Or use something like DebugKit to get a panel with all the queries by default (when in debug mode).
I have only two tables in my database with a one-to-many relationship between them (user hasMany messages) and am trying to get basic CRUD functionality going. Bake detects the associations correctly and specifies them correctly inside the model classes, but in controllers and views it looks like Cake doesn't know anything about those associations -- I don't even get a select tag for user_id when I go add a new message. Has anyone come across this problem before? What can I be doing wrong?
Table structure appears to be fine:
CREATE TABLE users (
id int(11) NOT NULL AUTO_INCREMENT,
username varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
email varchar(255) NOT NULL,
created datetime NOT NULL,
modified datetime NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `messages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`content` varchar(255) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
If you're using the console to bake your MVC files you could try that.
First bake the model files. Then bake the controller files using scaffold.
Then bake the view files.
Finally go back and bake the controller files without scaffold.
This should get you all basic CRUD functionality with all the associations you may have.
Hope that helps ...