SSMS: How can I get lower-cased keywords from the scripting engine? - ssms

I'm using SSMS v18.12.1 but this has been an annoyance for me for at least 10 years. I've used MS SQL Dev tools since SQL 7 and SQL 2000. At some point, it didn't matter anymore if the keywords were capitalized or not, but all of the tools capitalize EVERYTHING! (OK not everything but you know what I mean). I simply find it distracting, useless, and annoying.
I know that in Tools -> Options -> Text-Editor -> Transact-SQL -> IntelliSence I can set "Casing for built-in function names" to Lower Case. That handles about 5% of my fury.
If I write something like:
create table AWholeBunchaStuff(
Id int identity(1,1) not null,
SomeValue nvarchar(max) not null,
constraint pk_AWholeBunchaStuff primary key clustered (Id)
)
If I ever need to edit it in the future, right click the table and Script Table as -> Create to I get the following:
CREATE TABLE [dbo].[AWholeBunchaStuff](
[Id] [int] IDENTITY(1,1) NOT NULL,
[SomeValue] [nvarchar](max) NOT NULL,
CONSTRAINT [pk_AWholeBunchaStuff] PRIMARY KEY CLUSTERED (Id)
)
(btw I don't mind the brackets, even though I never include spaces in object names, and I should always include the schema, but don't)
From the searches I've made, it looks like SSMS does not have a setting to control this aspect of the scripting engine. At this point I'm willing to go with plugins (free or paid) or maybe another SQL editor all-together.
How can I have the scripted object output match how I wrote it?
Another possibility is something that will just lowercase all the keywords, Ctrl-Shift-L will lowercase everything, but that lower-cases my Object/Column names also!
Maybe I need to write my own plugin? Any advice? TIA

Related

Naming for contraints when creating a table

I see following SQL in a system:
create table Account
(
[AccountId] int not null,
[EquityStatus] int not null constraint DF_Account_EquityStatus default(1),
[DerivativeStatus] int not null constraint DF_Account_DerivativeStatus default(1),
[HasSecurityAgreement] tinyint not null constraint DF_Account_HasSecurityAgreement default(0),
...
)
Why it names every contraints for almost every column? Is there any benefit to do this?
You can let your system assign a system-generated name for your constraints but then it becomes very difficult, from a maintenance perspective, if you want to alter or drop a constraint later - you generally have to perform such operations by name and if you let the system auto-generate the name, you won't know the correct name to use.
In addition, if scripts are your primary means of deployment and you have multiple environments (e.g. development, staging, test, etc) then the system generated names will differ in each environment which makes it far more difficult if you want to compare two environments to establish current differences.

SQL - Storing undefined fields in a table

So, I have a few client that want to store user data, the thing is they want to store data without telling me what it is. What I mean is that, they will likely store things like username, first name, last name and email, but then there are a myriad of other things that are no defined and that can change.
So with that in mind, I want to create a table that can handle that data. I was thinking of setting up a table like this:
CREATE TABLE [dbo].[Details](
[Id] [int] NOT NULL,
[ClientId] [nvarchar](128) NOT NULL,
[ColumnName] [nvarchar](255) NOT NULL,
[ColumnValue] [nvarchar](255) NOT NULL,
CONSTRAINT [PK_Details] PRIMARY KEY CLUSTERED
(
[Id] ASC
)
Is this the best way to store this data, or am I making a mistake?
Please help me before I go ahead and create this table! :D
Just make clear to your clients that fields the database knows about, like a user number, name, and address can be searched fast, checked for consistency, and even be used for program control (such as some users see or can do what others cannot), whereas "undefined data" will not.
Then find out, if they really need single entities. Then the name/value approach is exactly the way to go. Maybe, however, it suffices to store one note per user, where they enter all their comments, memos, etc., i.e. just one text to hold all "undefined data". If possible this would be a better approach.

Linqpad can table with column same name as table name

Hello all i have a small issue with Linqpad with a poorly setup Database
Firstly i have a database where the creator has tables with column named the same as table which he is using as an enabled field.
In Addition to this these tables have the columns Content and Value.
After experimenting with this if the table has a column named the same as the Table it renames the column to Content and then Value if it has a column name similarly named.
if i then try to query (below) i loose the column with the same column name as the table. Does anyone know of any method to get around this. as it makes linqpad use impossible as this is prominent over all the database tables i am currently using?
Example below
If i have
CREATE TABLE [dbo].[TestTable](
[TestTableID] [int] NOT NULL,
[TestTable] [varchar](max) NULL,
[Content] [varchar](max) NULL,
[Value] [varchar](max) NULL
)
As you can see im missing the
What happens is that if your table "foo" contains a field named "foo", then this field gets renamed to "content" in linqpad.
In your case, the field "content" already exists, so you end up with only one of the two created in the context's table (thus the "missing" field).
As a workaround, you can try to avoid the collision by changing the names (table name, field name, content field name), or creating a view with aliased names to avoid collisions.
This got me going for the better part of an hour now, but I think I found a working solution for you.
the problem is the Linq-To-Sql provider in Linqpad itself. If you open up Visual Studio and create a context class based on your database, you will notice the column TestTable gets renamed to TestTable1.
So what I have done to take advantage of this, is created a new project of type "class library" - target Framework 4.0.
In this I added a new Linq-to-Sql class and dragged the TestTable into it.
Go into your class1.cs and insert: (I don't know if this is neccessary)
//I named my context L2S. Replace accordingly
public L2SDataContext context = new L2SDataContext();
Compile
Add a new connection to Linqpad using a typed context!
Connect to your server
Query!

SQL Indexing Strategy on Link Tables

I often find myself creating 'link tables'. For example, the following table maps a user record to an event record.
CREATE TABLE [dbo].[EventLog](
[EventId] [int] NOT NULL,
[UserId] [int] NOT NULL,
[Time] [datetime] NOT NULL,
[Timestamp] [timestamp] NOT NULL
)
For the purposes of this question, please assume the combination of EventId plus UserId is unique and that the database in question is a MS SQL Server 2008 installation.
The problem I have is that I am never sure as to how these tables should be indexed. For example, I might want to list all users for a particular event, or I might want to list all events for a particular user or, perhaps, retrieve a particular EventId/UserId record. Indexing options I have considered include:
Creating a compound primary key on EventId and UserId (but I
understand the index won't be useful when accessing by UserId on its
own).
Creating a compound primary key on EventId and UserId and a adding a
supplemental index on UserId.
Creating a primary key on EventId and a supplemental index on
UserId.
Any advice would be appreciated.
The indices are designed to solve performance problems. If you don't yet have such problem and cannot exactly know where you'll face troubles then you shouldn't create indexes. The indices are quite expensive. Because it not only takes up disk space but also causes the overhead of writing or modifying data. So you have to be clear understand what the specific performance problem you decide by creating an index. So you can appreciate the need to create it.
The answer to your question depends on several aspects.
It depends on the DBMS you are going to use. Some prefer single-column indexes (like Postgresql), some can take more advantage of multi-column indexes (like Oracle). Some can answer a query completely from a covering index (like sqlite), others cannot and eventually have to read the pages of the actual table (again, like postgres).
It depends on the queries you want to answer. For example, do you navigate in both directions, i.e., do you join on both of your Id columns?
It depends on your space and processing time requirements for data modification, too. Keep in mind that indexes are often bigger than the actual table that they index, and that updating indexes is often more expensive that just updating the underlying table.
EDIT:
When your conceptual model has a many-to-many relationship R between two entities E1 and E2, i.e., the logical semantics of R is either "related" or "not-related", than I would always declare that combined primary key for R. That will create a unique index. The primary motivation is, however, data consistency, not query optimization, i.e.:
CREATE TABLE [dbo].[EventLog](
[EventId] [int] NOT NULL,
[UserId] [int] NOT NULL,
[Time] [datetime] NOT NULL,
[Timestamp] [timestamp] NOT NULL,
PRIMARY KEY([EventId],[UserId])
)

What is the purpose of constraint naming

What is the purpose of naming your constraints (unique, primary key, foreign key)?
Say I have a table which is using natural keys as a primary key:
CREATE TABLE Order
(
LoginName VARCHAR(50) NOT NULL,
ProductName VARCHAR(50) NOT NULL,
NumberOrdered INT NOT NULL,
OrderDateTime DATETIME NOT NULL,
PRIMARY KEY(LoginName, OrderDateTime)
);
What benefits (if any) does naming my PK bring?
Eg.
Replace:
PRIMARY KEY(LoginName, OrderDateTime)
With:
CONSTRAINT Order_PK PRIMARY KEY(LoginName, OrderDateTime)
Sorry if my data model is not the best, I'm new to this!
Here's some pretty basic reasons.
(1) If a query (insert, update, delete) violates a constraint, SQL will generate an error message that will contain the constraint name. If the constraint name is clear and descriptive, the error message will be easier to understand; if the constraint name is a random guid-based name, it's a lot less clear. Particulary for end-users, who will (ok, might) phone you up and ask what "FK__B__B_COL1__75435199" means.
(2) If a constraint needs to be modified in the future (yes, it happens), it's very hard to do if you don't know what it's named. (ALTER TABLE MyTable drop CONSTRAINT um...) And if you create more than one instance of the database "from scratch" and use system-generated default names, no two names will ever match.
(3) If the person who gets to support your code (aka a DBA) has to waste a lot of pointless time dealing with case (1) or case (2) at 3am on Sunday, they're quite probably in a position to identify where the code came from and be able to react accordingly.
To identify the constraint in the future (e.g. you want to drop it in the future), it should have a unique name. If you don't specify a name for it, the database engine will probably assign a weird name (e.g. containing random stuff to ensure uniqueness) for you.
It keeps the DBAs happy, so they let your schema definition into the production database.
When your code randomly violates some foreign key constraint, it sure as hell saves time on debugging to figure out which one it was. Naming them greatly simplifies debugging your inserts and your updates.
It helps someone to know quickly what constraints are doing without having to look at the actual constraint, as the name gives you all the info you need.
So, I know if it is a primary key, unique key or default key, as well as the table and possibly columns involved.
By correctly naming all constraints, You can quickly associate a particular constraint with our data model. This gives us two real advantages:
We can quickly identify and fix any errors.
We can reliably modify or drop constraints.
By naming the constraints you can differentiate violations of them. This is not only useful for admins and developers, but your program can also use the constraint names. This is much more robust than trying to parse the error message. By using constraint names your program can react differently depending on which constraint was violated.
Constraint names are also very useful to display appropriate error messages in the user’s language mentioning which field caused a constraint violation instead of just forwarding a cryptic error message from the database server to the user.
See my answer on how to do this with PostgreSQL and Java.
While the OP's example used a permanent table, just remember that named constraints on temp tables behave like named constraints on permanent tables (i.e. you can't have multiple sessions with the exact same code handling the temp table, without it generating an error because the constraints are named the same). Because named constraints must be unique, if you absolutely must name a constraint on a temp table try to do so with some sort of randomized GUID (like SELECT NEWID() ) on the end of it to ensure that it will uniquely-named across sessions.
Another good reason to name constraints is if you are using version control on your database schema. In this case, if you have to drop and re-create a constraint using the default database naming (in my case SQL Server) then you will see differences between your committed version and the working copy because it will have a newly generated name. Giving an explicit name to the constraint will avoid this being flagged as a change.