Cakephp 3 with SQL Server 2012 - sql-server-2012

I am writing RESTful API using cakephp 3.6 for SQL Server 2012. Some API's created and working fine.
But unfortunately not for one table. This table have primary key but its value is not auto incremented. When I am assigning its value API its generating error
SQLSTATE[23000]: [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Cannot insert the value NULL into column 'Id', table 'AccountsLive.dbo.Books'; column does not allow nulls. INSERT fails
I can't keep its primary key auto incremented.
When I create view to add it from browser. It does not create field for Id field. Then I try to create input field for Id field, its not going to display it on books input form.
Please help me to solve this issue, I will be thankful to you.

The assumption is that your id columns will be auto-incrementing. If there's a good reason(*) why you can't do that here, you'll need to add the input field (as you found), and also add it to the _accessible list in the Book entity.
(*) The number of situations where having your id column not auto-incrementing (and not a UUID) makes sense is really very small. Be very sure that this really does apply to you, as it moves all responsibility for avoiding overwriting records due to duplication onto you instead of the database.

Related

MS Access not working after swapping ODBC linked table with ODBC linked view

My company uses an SQL Server database, with Access as a front end. One of the biggest tables on the server is called tbl_Contacts. The primary key, "ContactID" was setup as an auto-incrementing "int" data type. Turns out yesterday afternoon, the limits of the "int" type ran out, and no new contacts could be added to the table.
At first I tried just updating the data type to "bigint", but then Access couldn't recognize the data type and showed "Deleted" for all the fields in the Contacts table.
I read a bunch of different articles and realized that Access 2010 cannot understand the bigint data type, and that I would need to cast the field to a different type that Access could understand.
I ended up making a View of tbl_Contacts and used this SQL to modify the ContactID field, including all the other fields in the table as is.
CAST(ContactID AS Decimal(15, 0)) AS ContactID
I then renamed the old linked table in Access to tbl_Contacts_OLD, added the new ContactsView table into Access with an ODBC connection, and renamed the View to "tbl_Contacts".
I thought everything was working, because I could add new records to the table again, but it turns out some things are still not working.
The only thing I can imagine is that other tables in my database are expecting "ContactID" to be a "Long Integer", and they aren't liking it being a "Decimal".
When I try to use a form that adds data to a table "tbl_CallLog", which links to "tbl_Contacts", I get this error.
Run-time error '3101'
The MS Access database engine cannot find a record in the table 'tbl_Contacts' with key matching field(s) 'ContactID'
Is there another data type I should be casting to that Access 2010 can recognize and use? Is there maybe a step I still need to do, perhaps casting the decimal value to yet another data type within Access?
Do I need to convert the data type on all other tables that reference the original Contacts table so they're linked fields are now decimal data types?
BigInt can be understood only by Access 2016.
The data types for a record id should be either Long or GUID. Long is by far the most commonly used.
So this isn't the best solution in the world, but I finally got my problem fixed doing the following.
My tbl_Contacts table only has 99k records in it, but due to various reasons, and the table being 20 years old, the IDENTITY SEED was at 2+ billion, the limits of the "int" datatype. I looked through the IDs and found a gap of 120k numbers, so I used this query to reset my seed value.
DBCC CHECKIDENT ('[tbl_Contacts]', RESEED, -92801);
GO
I've created several test contacts now, and the first one had the ID number -92800.
This should hold me until I can get a new CRM system in place in the middle part of the year.
Thanks for the comments, Gustav.

Apex 4.0.2 Primary Key Incrementation from with-in an Application

So as apart of of a project I am doing I have been restricted on the editing of the Database from which I am building this application. I can not directly make changes to the Database from the SQL Command Prompt, all changes and new entries have to be made through Apex. Just clarifying this.
So I have a table TAXIUSER that has a primary key of TAXIUSERID. The primary key format for data currently in the Database is as follows:
UID0001
UID0002
and so on. Currently the user has to manually enter a new primary key each time they add an entry to the table. How through the Apex application solely (I can't use SQL Workshop either!) can I achieve something that would allow the user to not have to manually enter the primary key and preferably have it increment still in the above format.
EDIT: Sorry I should clarify I am using an Form on a Table with Report and version 11g.
You can do this by creating a read only item with a default value (or a computation) of
SELECT
'UID'||LPAD(MAX(SUBSTR(taxiuserid,4) + 1),4,0)
FROM
taxiuser;
Note that your prerequisites (no access to db) are forcing this to be a flawed approach:
Errors out with primary key constraint violation if 2 or more users are creating records at the same time. You could minimize the risk by calculating the new value on submit but then the user will not see the value when they're creating the user
Only works for the first 9999 users
Edit: If you use the computation after submit method, you will need to add condition to allow edits to made to existing entries. Otherwise the computation will attempt to change the primary key of that entry causing an error. To do this simply add a condition of Value in Expression 1 is Null, then specify the column from which the data is being entered into the table, like as follows:
P8_TAXIUSERID
This essentially means the computation will only ever attempt a value to TAXIUSERID when P8_TAXIUSERID (the column from which your are entering the data) contains a null value.

Get RowID on Progress Insert

I have a table which doesn't have primary key. I needed to add a primary key to the table so I added a column called 'ID'. I am attempting to use the rowid to insert unique ids into this new column. How would I go about getting the rowid when inserting a new record. This is in a Progress database.
INSERT INTO PUB.DETAILS (LASTUPDATED, FORMERVALUE, NEWVALUE, ID)
VALUES ('09/16/2015', 'NEW ITEM', 'ESISTING ITEM', '?')
Progress databases doesn't necessary have a key. At least not in the "SQL way". The keys (as well as the relations) are defined by the business logic (ie how you use the fields.
Since you seem to be working with a database that's in use it might simply be that you don't need a key - there's some kind of logic there already that does the job?
There is a thing called "sequence" in Progress databases that can be used to increase a value - how to access them using odbc or sql I really don't know.
In Progress ABL (4GL) you would say NEXT-VALUE(sequence-name)
Here's some help about SQL and Progress dbs.
Just set your ID column to autoincrement, so you won't need to know the last inserted one.

How does hibernate populate ids of auto generated fields?

Say i have an entity with an auto generated primary key. Now if i try to save the entity with values of all other fields which may not be unique.
The entity gets auto populated with the id of the row got inserted. How did it get hold of that primary key value?
EDIT:
If the primary key column is say identity column whose value is totally decided by the database. So it does an insert statement without that column value and the db decides the value to use does it communicate back its decision (I dont think so)
Hibernate use three method for extracting the DB auto generated field depending on what is support by the jdbc driver or the dialect you are using.
Hibernate extract generated field value to put it back in the pojo :
Using the method Statement.getGeneratedKeys (Statement javadocs)
or
Inserting and selecting the generated field value directly from the insert statement. (Dialect Javadocs)
or
Executing a select statement after the insert to retrieve the generated IDENTITY value
All this is done internally by hibernate.
Hope it`s the explication you are looking for.
This section of the Hibernate documentation describes the auto generation of ids. Usually the AUTO generation strategy is used for maximum portability and assuming that you use Annotations to provide your domain metadata you can configure it as follows:
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
Anyway the supplied link should provide all the detail you need on generated ids.
When you create an object with the, say, sequence-derived surrogate primary key, you pass it to the Hibernate session with that field set to the value that Hibernate interprets as "not assigned", by default 0. This field is not populated with the assigned value until the corresponding record is not inserted into the database table. You can trigger insertion by either explicitly calling flush() on the hibernate session or performing a database read in the same session. After that you can check the value of that field and it will be assigned rather than 0.

identity column in Sql server

Why does Sql server doesn't allow more than one IDENTITY column in a table?? Any specific reasons.
Why would you need it? SQL Server keeps track of a single value (current identity value) for each table with IDENTITY column so it can have just one identity column per table.
An Identity column is a column ( also known as a field ) in a database table that :-
Uniquely identifies every row in the table
Is made up of values generated by the database
This is much like an AutoNumber field in Microsoft Access or a sequence in Oracle.
An identity column differs from a primary key in that its values are managed by the server and ( except in rare cases ) can't be modified. In many cases an identity column is used as a primary key, however this is not always the case.
SQL server uses the identity column as the key value to refer to a particular row. So only a single identity column can be created. Also if no identity columns are explicitly stated, Sql server internally stores a separate column which contains key value for each row. As stated if you want more than one column to be having unique value, you can make use of UNIQUE keyword.
The SQL Server stores the identity in an internal table, using the id of the table as it's key. So it's impossible for the SQL Server to have more than one Identity column per table.
Because MS realized that better than 80% of users would only want one auto-increment column per table and the work-around to have a second (or more) is simple enough i.e. create an IDENTITY with seed = 1, increment = 1 then a calculated column multiplying the auto-generated value by a factor to change the increment and adding an offset to change the seed.
Yes , Sequences allow more than one identity like columns in atable , but there are some issues here . In a typical development scenario i have seen developers manually inserting valid values in a column (which is suppose to be inserted through sequence) . Later on when a sequence try inserting value in to the table , it may fail due to unique key violation.
Also , in a multi developer / multi vendor scenario, developers might use the same sequence for more than one table (as sequences are not linked to tables) . This might lead to missing values in one of the table . ie tableA might get the value 1 while tableB might use value 2 and tableA will get 3. This means that tableA will have 1 and 3 (missing 2).
Apart from this , there is another scenario where you have a table which is truncated every day . Since Sequences are not having any link with table , the truncated table will continue to use the Seq.NextVal again (unless you manually reset the sequence) leading to missing values or even more dangerous arthmetic overflow error after sometime.
Owing to above reason , i feel that both Oracle sequences and SQL server identity column are good for their purposes. I would prefer oracle implementing the concept of Identity column and SQL Server implementing the sequence concept so that developers can implement either of the two as per their requirement.
The whole purpose of an identity column is that it will contain a unique value for each row in the table. So why would you need more than one of them in any given table?
Perhaps you need to clarify your question, if you have a real need for more than one.
An identity column is used to uniquely identify a single row of a table. If you want other columns to be unique, you can create a UNIQUE index for each "identity" column that you may need.
I've always seen this as an arbitrary and bad limitation for SQL Server. Yes, you only want one identity column to actually identify a row, but there are valid reasons why you would want the database to auto-generate a number for more than one field in the database.
That's the nice thing about sequences in Oracle. They're not tied to a table. You can use several different sequences to populate as many fields as you like in the same table. You could also have more than one table share the same sequence, although that's probably a really bad decision. But the point is you could. It's more granular and gives you more flexibility.
The bad thing about sequences is that you have to write code to actually increment them, whether it's in your insert statement or in an on-insert trigger on the table. The nice thing about SQL Server identity is that all you have to do is change a property or add a keyword to your table creation and you're done.