I was using the SDK for CRM, and printed out the PK on a bunch of instances of one of our entities. I repeated it with the database's filtered views, and got the same answer:
1a6c691d-391a-de11-8b0e-0050568407cb
bd7b0ff0-391a-de11-8b0e-0050568407cb
ed272bfe-391a-de11-8b0e-0050568407cb
... and so on ...
These don't appear to be valid GUIDs. For one, they LOOK wrong - they're nearly identical, a property that GUIDs haven't had since the old version 1 & 2 GUIDs that were based on MAC addresses and clock time. Moreover, however, is the fact that a certain nibble in a GUID indicates the GUID's version - that nibble is incorrect here. (First nibble of the third section, ie: 1a6c691d-391a-**d**e11-8b0e-0050568407cb) - valid values are 1-5) (Generate a GUID using MS's GUID Generator - that slot will always be 4. (At least for the version I have.))
Are these GUIDs, or just IDs, and how do I know?
You are right that they are GUIDs and that they are sequential. These keys are not generated by CRM. They are generated by SQL Server.
SQL Server has a GUID type called uniqueidentifier. It can be configured as either NEWID() or NEWSEQUENTIALID(). NEWID() will generate a new GUID every time. NEWSEQUENTIALID() generates a GUID the first time and then sequentially increments it on subsequent database inserts.
So you have discovered that Dynamics CRM is configured for NEWSEQUENTIALID().
More info about this is here: http://www.mssqltips.com/tip.asp?tip=1600
Related
I have a JSON document with two properties deviceIdentity, version.
Partition Key for my collection is deviceIdentity.
My JSON documents comes with different versions I want to keep all versions of this document.
Like:
deviceIdentity1, v1
deviceIdentity1, v2
Two documents should be there.
Problem is since my PK is deviceIdentity, it is always updating the existing record even though I have defined a unique key constraint on deviceIdentity, version.
enter image description here
Any pointers will be of help!
I believe you are confusing partition key with primary key.
Partition key determines how data is scaled horizontally. This should not be unique as otherwise any read except exact document lookup would require to scan all partitions, which would be innefficient. In your case deviceIdentity may be a suitable candidate - all versions of the same device would fall to same partition.
Primary key is your document identity (the field id). As you already noticed, there can be only 1 document with given id. The id field MUST be unique per document you want to store. In your case, you could use a combination values like "deviceIdentity1, v2" as the identity. Or, you could use technical unique id, like a guid.
Also, note that by Unique keys in Azure Cosmos DB:
By creating a unique key policy when a container is created, you ensure the uniqueness of one or more values per partition key.
Meaning if your partition key is deviceIdentity then you don't have to duplicate the deviceIdentity in unique constraint part. Constraint on /version would suffice to ensure that every single partition/device has at most one document per version.
Thanks for all the answers.
The problem was we have an old legacy system where “id “was an already heavily used property but it did not have unique values.
So whenever a document comes with a different version it was updating as “id” in cosmos has predefined meaning that is UPSERT of any arriving document is done on unique id value, in our case id is never unique.
Solution we found.
Whenever a document comes we process it in an azure function and swap “id” column with the value of unique “deviceidentity” value and save it, as structure of JSON cannot be changed as stated by our client and while reading these documents we have exposed an API which does the swapping again and sends the document to the requesting client as it is.
for a project I need to change the AIF service called "SalesSalesEInvoice". In particular, I need to retrieve the CustPaymModeTable on the result XML.
In the query used by the service, this table is present and is joined with CustTrans (relationship based on PaymMode field).
We debugged the service execution and we've observed that the table is not retrieved because it is not linked via surrogate key (AifSecurityInference.inferField()).
Did you ever had (and solved) that problem?
How can we force the recovery of the table when the join is not based on recid?
It looks like there is a range set in CustPaymModeTable. So please verify if there is record exists with that range value.
I am having an issue with an SQLite database. I am using the SQLite ODBC from http://www.ch-werner.de/sqliteodbc/ Installed the 64-bit version and created the ODBC with these settings:
I open my Access database and link to the datasource. I can open the table, add records, but cannot delete or edit any records. Is there something I need to fix on the ODBC side to allow this? The error I get when I try to delete a record is:
The Microsoft Access database engine stopped the process because you and another user are attempting to change the same data at the same time.
When I edit a record I get:
The record has been changed by another user since you started editing it. If you save the record, you will overwrite the changed the other user made.
Save record is disabled. Only copy to clipboard or drop changes is available.
My initial attempt to recreate your issue was unsuccessful. I used the following on my 32-bit test VM:
Access 2010
SQLite 3.8.2
SQLite ODBC Driver 0.996
I created and populated the test table [tbl1] as documented here. I created an Access linked table and when prompted I chose both columns ([one] and [two]) as the Primary Key. When I opened the linked table in Datasheet View I was able to add, edit, and delete records without incident.
The only difference I can see between my setup and yours (apart from the fact that I am on 32-bit and you are on 64-bit) is that in the ODBC DSN settings I left the Sync.Mode setting at its default value of NORMAL, whereas yours appears to be set to OFF.
Try setting your Sync.Mode to NORMAL and see if that makes a difference.
Edit re: comments
The solution in this case was the following:
One possible workaround would be to create a new SQLite table with all the same columns plus a new INTEGER PRIMARY KEY column which Access will "see" as AutoNumber. You can create a unique index on (what are currently) the first four columns to ensure that they remain unique, but the new new "identity" (ROWID) column is what Access would use to identify rows for CRUD operations.
I had this problem too. I have a table with a primary key on a VARCHAR(30) (TEXT) field.
Adding an INTEGER PRIMARY KEY column didn't help at all. After lots of testing I found the issue was with a DATETIME field I had in the table. I removed the DATETIME field and I was able to update record values in MS-Access datasheet view.
So now any DATETIME fields I need in SQLite, I declare as VARCHAR(19) so they some into Access via ODBC as text. Not perfect but it works. (And of course SQLite doesn't have a real DATETIME field type anyway so TEXT is just fine and will convert OK)
I confirmed it's a number conversion issue. With an empty DATETIME field, I can add a time of 01-01-2014 12:01:02 via Access's datasheet view, if I then look at the value in SQLite the seconds have been rounded off:
sqlite> SELECT three from TEST where FLoc='1020';
2014-01-01 12:01:00.000
SYNCMODE should also be NORMAL not OFF.
Update:
If you have any text fields with a defined length (e.g. foo VARCHAR(10)) and the field contents contains more characters than the field definition (which SQLite allows) MS-Access will also barf when trying to update any of the fields on that row.
I've searched all similar posts as I had a similar issue with SQLite linked via ODBC to Access. I had three tables, two of them allowed edits, but the third didn't. The third one had a DATETIME field and when I changed the data type to a TEXT field in the original SQLite database and relinked to access, I could edit the table. So for me it was confirmed as an issue with the DATETIME field.
After running into this problem, not finding a satisfactory answer, and wasting a lot of time trying other solutions, I eventually discovered that what others have mentioned about DATETIME fields is accurate but another solution exists that lets you keep the proper data type. The SQLite ODBC driver can convert Julian day values into the ODBC SQL_TIMESTAMP / SQL_TYPE_TIMESTAMP types by looking for floating point values in the column, if you have that option enabled in the driver. Storing dates in this manner gives the ODBC timestamp value enough precision to avoid the write conflict error, as well as letting Access see the column as a date/time field.
Even storing sub-second precision in the date string doesn't work, which is possibly a bug in the driver because the resulting TIMESTAMP_STRUCT contains the same values, but the fractional seconds must be lost elsewhere.
It is specifically mention that WAMS needs a int ID column to work in SQL Azure. However when developing enterprise apps over distributed databases, GUIDs are the preferred Primary key to have. How does one get around avoiding int ID column and support GUID?
If that cannot be done then how does one go about syncing data on the cloud from multiple standalone databases on various tablets/mobile the app using WAMS is running on?
An update on this issue - as of last week, the mobile services now support arbitrary strings as the ids for the column - check out this post for more information. You can now insert data with an 'id' value (which you couldn't before), so you can use a Guid value on insert. Also, if you don't send anything on the Id column on insert (or that value is set to null), the server will by default generate an unique identifier for the column.
At present, I don't think that its possible to use a GUID in the ID column. The documentation for the Mobile Services server side scripts specify that for the Delete function, the ID must be a javascript Number type. As far as I can see, all of the available sample code, and the code that you can download from the portal is quite explicit in using an integer type for the ID.
You'll have to come up with a way of generating a unique integer value whenever a new record is created. The example here uses a tick count in Insert script, which is probably OK for a low volume application, but it would need to be made more robust, perhaps by generating a number based on the user's identity and combining it with the tick count.
I'm a little late to this but I have found you can use a GUid as a primary key to a mobile services table. A couple of points though. Set the JSON property to lower case "id" and use a nullable guid, this allows inserting when there a default on the id column (NewId())
[JsonProperty(PropertyName = "id")]
public Guid? Id { get; set; }
Ash..
I have a couple of tables I ported over to a new database. Everything is exactly the same from the legacy one to the new one. The back-end code that submits the user generated data to the database is also the same. When I submit changes to the database, all of the submitted information populates the correct columns but the column that stores the GUID populates with all 0's. When I enter in the columns manually using SQL Server Management Studio, the GUID gets populated as it does in the legacy version. Am I missing something?
I've had a similar issue with Entity Framework in the past, even though I have newid() set as default/initial value on the column. Due to time constraints, I didn't spend much time to resolve it and instead set the Guid property manually/explicitly to Guid.NewGuid() prior to saving.
When you ported over the tables, you must not have ported over the default value for one of the columns. E.g.
CREATE TABLE blah (
blahID UNIQUEIDENTIFIER PRIMARY KEY DEFAULT NEWID()
)