Simulate DEX_ROW_ID in a SQL View Using ROW_NUMBER() – #MSDYNGP

I have a requirement in which I have to access a SQL view from within my customisation dictionary, in order to create a custom lookup for users to select a value based on an Extender form and an Extender lookup. Easiest option is to create an Extender view (which in turn creates a SQL view for us).

Now, this is the view that I am suppose to refer to from my custom dictionary. Dexterity allows us to refer to any SQL object by simply create a TABLE definition and mention the SQL object (table or view) name as the physical name.

Dex View

Everything looks perfect till you actually see below error messages at runtime:

Dex View - Error 1

Dex View - Error 2

Error message is quite obvious; you do not have DEX_ROW_ID in that SQL view that you are referring to. Every single Dexterity table must have DEX_ROW_ID at the backend. It cannot afford to not have one.

So how am I going to resolve this? By simply adding a record number dynamically to the SQL view created by Extender. How to do that? By adding the T-SQL function ROW_NUMBER(). This is how I achieved it:



Definition of ROW_NUMBER() can be found here: ROW_NUMBER (Transact-SQL).

A simple yet powerful SQL function has given me the power to do what I wanted in no time. Oh, and my custom lookup referring to this view is working like a charm. Users are happy and so am I.


Move Expired SOP Quotes To History – Leslie Vail

Leslie Vail has posted an article at a time when I am currently working on closing down thousands and thousands of SOP quotes which users failed to close down. It’s about a SQL Script which moves all expired SOP quotes to history.

(Some really lame) reasons I use to hear for not closing down quotes:

1. We don’t know when that quote would be materialised.

Seriously? Gotta be kidding me. If it’s a quote of age 2+ years and you still don’t know whether it would get materialised or not, then something is wrong fundamentally.

2. If it’s voided, we won’t be able to copy the line items of that quote.

Wrong. You can. Copying line items from an SOP document is very much possible, even if it’s transferred or voided.

3. We don’t know whether the comments that we had added specific to that quote would be available for us to reuse it.

Answer is a positive YES. You can reuse the comments, because comments are NOT stored on that document but on Comments Master. Just select the ID and there it is. Unless, you have edited that comment on the document. But again, come on, it’d take 5 mins for you to inquire the voided one, copy the comment text and paste it on new one.

And so on…


Seven Sins Against T-SQL Performance – Grant Fritchey on Simple Talk

UPDATE: this was drafted long ago, but couldn’t really got to post it till now. You might find this post a bit old, BUT it’s quite relevant even now and extremely informative post.

I came across this gem of an article which lists out 7 things that affect T-SQL performance.

I do not want to take anything out from that article and post it here, as you would realize by reading the original post, you would learn some very important concepts.

Read it here: The Seven Sins Against T-SQL Performance.


Implicit Conversions Causing Deadlocks in SQL Server

Quite an interesting but crucial post up there on Sans SQL blog.

The post explains that Implicit conversions in SQL Server could actually trigger a deadlock. And there are definitions for each important term (such as deadlock, implicit conversion, etc.) with an example.

I believe this post would be useful for those who work extensively on SQL Server.


Formatting SQL Procedures

Have you ever opened a standard GP stored procedure?

I do it at least on a weekly basis and have always found it impossible to read as it is. So I end up aligning the procedure first and then read it to understand the logic.

Not anymore. David has shared information on some portals which does this in seconds and give us an aligned code.

Standing out from his list is Poor SQL, from what I learned from my usage.

And there is a plugin for SSMS which does this from within SSMS. This tool is called SSMS Tools Pack.

Happy aligning.


Item Decimal Places Currency & Inventory Adjustments

Q: From where does the Inventory Adjustment entry retrieve a product’s Decimal Places Currency value?

A: When we create a product, this value will be defaulted from the Functional Currency of that company. While entering an Inventory Adjustment for this product, the decimal places currency value will then be retrieved from the product master record.

I realized this when I faced an issue couple of days back. I got a requirement where, I have to facilitate an automated program that will replicate a product information (Master, Quantities/Site, Vendors, Currencies & Price List) from one company to another. Of course, with necessary changes that are specific to the destination company.

It worked merrily till both companies had functional currencies with same number of decimal places. I had to extend this program on to another company, whose functional currency supports 3 decimal places. Now you might have realized the issue. My program, quite honestly, was written with a hardcoded value of 2 decimal places.

When I created some products on my new company using this program, I could not enter Inventory Adjustments with 3 decimal places. It was always 2. Upon spending some time on this, I realized what I have mentioned at the start of this post. You cannot override this at all.

So those who write customization like what I have explained above, beware of all such nuances which will play very crucial role in day-to-day transactions.


GP Homepage Layout Mass Update – Thru’ SQL

I love SQL. Simply because, it eases lot of pain in doing some redundant work.

When you create a user, by default, GP creates the following segments on his/her homepage:

1. To Do (Reminders/Tasks)
2. My Reports
3. Microsoft Outlook
4. Quick Links
5. Connect (links to Online Resources such as CustomerSource, Forums, Blogs, etc.)
6. Metrics (quick dashboards for users)

All of the above work perfectly, but at some stages (especially when you are working on a GP Terminal Server) some of these components would halt GP for a while, not allowing users to do anything.

One classic example is Microsoft Outlook. We recently migrated our Email Services to Microsoft Office 365. For those users who use Thin Client to on their day-to-day job, Terminal Server is THE destination. Quite obviously, Terminal Server has got Outlook installed.

Before Office 365, Outlook profile used to connect to our on-premise Exchange Server. After migration, we had to change the profile from Exchange Server to Office 365 hosting server.

Whenever a user logs on to Terminal Server and opens GP, GP will halt for at least 3-5 mins to get this Outlook configured. I am getting calls from users (yes, even now) that their GP session does not work and they are not able to do anything. Following icon shows up on their taskbar when this happens:

It didn’t take me much time to realize that all these users had added Microsoft Outlook on their GP homepage.

“Do we really need Outlook on GP homepage?” is a question to be asked to oneself. Yes, Microsoft has integrated your ERP with one of the most used product by maximum business users. Agreed. But is that alone a reason for you to use it? Let’s not get into that argument in this post, anyways.

I had to take a stand and remove Microsoft Outlook from those users’ homepage. But then, I don’t know, right now, about how many users out of 100+ total users have added Outlook on their homepage.

Certainly not without the help of a SQL query.

The table where this information has got stored is SY08100 (Technical Name: syHomePageLayout). In this table, the column SectionID denotes the sections which are available for a user to add to his/her homepage. Following is the legend:

1 – To Do (Reminders/Tasks/Cues)
2 – Microsoft Outlook
3 – Metrics (quick dashboards for users)
4 – My Reports (links to users’ favorite reports and smartlists)
5 – Quick Links (links to users’ frequently used windows)
6 – Connect (links to Online Resources for GP such as Forums, Blogs, etc.)

Typically, for each user, this table will contain 6 rows, each row denoting each of above section. SY08100 also contains a column named Visible. This denotes whether or not to show a particular section on GP homepage.

For instance, if user SA has setup his GP homepage to show To Do, My Reports & Quick Links to show up, the following will be SY08100 records:

So, if I want to hide Microsoft Outlook from all users’ homepage, I just have to execute the following SQL query on DYNAMICS database:

UPDATE SY08100 SET Visible = WHERE SectionID = 2

We must also understand one thing. Users can always add this again thru’ Customize this page… option. So this is NOT A PERMANENT SOLUTION.

Whenever there is a necessity, as in my case, you can certainly rely on this SQL method to do a homepage layout mass update.


SQL Tip: Find Table(s) Having A Particular Column

This SQL query is my savior for a long time now. Thought I would just share it with all budding SQL developers.

Q: How to find the table(s) which contain a particular column which I know?
A: Below is the query that would do the trick.

SELECT name 
FROM sys.objects 
WHERE object_id IN 
SELECT object_id 
FROM sys.columns 
WHERE name = [columnname] –Column which you would want to locate

This query will return all tables which contains the specific column. And this query also would save your time immensely.


Perils of Using of DEX_ROW_ID on Customization / Integration – David

This one is certainly a nasty issue, if we are going to use DEX_ROW_ID value on customization or integration.

I have personally fallen into a trap by using DEX_ROW_ID on my customization. But now, it’s all wisdom out of that bad experience.

Only time when I normally depend on a DEX_ROW_ID is to sort records to understand which record was entered last in the table. That itself may not be always correct. So we may have to add other logical fields that are relevant to a particular record.

For instance, if I have to list out transactions entered on a particular day and check in the order in which the records are created, I would use the Transaction Date and DEX_ROW_ID as SORT ORDER.

There are many other reasons, but restrict yourself to use DEX_ROW_ID only for selecting records and analyze it.