Oracle persistent column alias - sql

I am an Oracle end user, not a database developer or admin.
Our database has some typos in column names, similar to a column being named ADRESS2 instead of ADDRESS2
I have to use these columns in my queries, and it's hard to remember which typo applies to which column. Also, I'm kind of anal persnickety about the way this makes my code look (not so professional).
I suspect there is no chance of getting these columns actually renamed in production -- it would be a low priority with lots of dependencies.
What is the best practice in this situation?
I can think of a couple options:
add comments that the typo is intentional
wrap the table with a select(bad_name good_name, * from table)
create a view based on the above
But is there any way to do something like:
DECLARE address2 CHAR(8) := 'adress2';
And use in a query, but returning the values of ADRESS2 instead of the char "adress2".
The desired solution would be a practice that:
wouldn't increase the complexity of the query
would be recognized by developers as a response to a situation where column names are unwieldy or misleading

I think about the only legitimate response is a view. If I were in your situation, I'd fix the column typos. Failing that, I would create a view.
But, something in your question makes me think that you're willing to consider something more "out there", so here it is:
alter table sample_table add address2
invisible generated always as ( addres2 || '') virtual;
This is very likely to not impact any of your applications, as nothing will see the ADDRESS2 column unless they explicitly ask for it.
But, it makes it available for you persnickity types.
Keep in mind that the function ADDRES2 || '' means your queries won't use indexes on the columns you access this way.
Repeat: I would change the column names or make a view.

Related

SQL "$" symbol usage

I've been looking at a SQL query & output and am trying to figure out the impact the "$" would have in the query if any.
I cannot find anything about the use of the "$" symbol and want to make sure. I've searched the w3 schools, here, and Oracle documentation (as I'm using an Oracle database)
select * from v$example_users
The above is the code that I'm looking at. Will the "$" symbol in the middle of the table name? I.e. is the table called "v$example_users" or does the "$" somehow affect the table?
There's no special functionality to the $ character.
The v$ views are public synonyms of Oracle's dynamic performance views. They are given these "unconventional" names to make them easy to recognize.
Most Oracle identifiers (table names, column names, etc.) you see in the wild usually include only alphanumeric characters. This is largely because it's easy to type and it reduces confusion with math operators, parenthesis, and other delimiters. This is also true for all databases I know.
However, you can actually use other symbols for table names (or other "objects") if you want to. If you do, you will probably need to quote the name -- every time. That is, when you create the table, when you insert a row, when you delete and update it, and on every single select query where you use it. It's perfectly legal, so if you need it, use it.
And, there's no performance penalty to pay. For Oracle there's no difference.
For example:
create table "Car+Price" (
id number(6),
"list&price" number(6),
"%discount" number(3),
"used?" number(1)
);
But then a query would be:
select id, "list&price", "%discount"
from "Car+Price"
where "used?" = 1;
See? Works! Does it look nice? er... not really. Besides, it looks quite error prone to me.
In my opinion, I would strongly recommend against using it (if possible) since it makes code harder to read, it's more difficult to debug, some ORMs don't really deal well with it, and a myriad of other reasons.
Just stay away from it, as long as you can.

Is using JOINs to avoid numerical IDs a bad thing? [duplicate]

This question already has answers here:
Performance of string comparison vs int join in SQL
(5 answers)
Closed 9 years ago.
Yesterday I was looking at queries like this:
SELECT <some fields>
FROM Thing
WHERE thing_type_id = 4
... and couldn't but think this was very "readable". What's '4'? What does it mean? I did the same thing in coding languages before but now I would use constants for this, turning the 4 in a THING_TYPE_AVAILABLE or some such name. No arcane number with no meaning anymore!
I asked about this on here and got answers as to how to achieve this in SQL.
I'm mostly partial to using JOINS with existing type tables where you have an ID and a Code, with other solutions possibly of use when there are no such tables (not every database is perfect...)
SELECT thing_id
FROM Thing
JOIN ThingType USING (thing_type_id)
WHERE thing_type_code IN ('OPENED', 'ONHOLD')
So I started using this on a query or two and my colleagues were soon upon me: "hey, you have literal codes in the query!" "Um, you know, we usually go with pks for that".
While I can understand that this method is not the usual method (hey, it wasn't for me either until now), is it really so bad?
What are the pros and cons of doing things this way? My main goal was readability, but I'm worried about performance and would like to confirm whether the idea is sound or not.
EDIT: Note that I'm not talking about PL/SQL but straight-up queries, the kind that usually starts with a SELECT.
EDIT 2:
To further clarify my situation with fake (but structurally similar) examples, here are the tables I have:
Thing
------------------------------------------
thing_id | <attributes...> | thing_type_id
1 3
4 7
5 3
ThingType
--------------------------------------------------
thing_type_id | thing_type_code | <attributes...>
3 'TYPE_C'
5 'TYPE_E'
7 'TYPE_G'
thing_type_code is just as unique as thing_type_id. It is currently also used as a display string, which is a mistake in my opinion, but would be easily fixable by adding a thing_type_label field duplicating thing_type_code for now, and changeable at any time later on if needed.
Supposedly, filtering with thing_type_code = 'TYPE_C', I'm sure to get that one line which happens to be thing_type_id = 3. Joins can (and quite probably should) still be done with the numerical IDs.
Primary key values should not be coded as literals in queries.
The reasons are:
Relational theory says that PKs should not convey any meaning. Not even a specific identity. They should be strictly row identifiers and not relied upon to be a specific value
Due to operational reasons, PKs are often different in different environments (like dev, qa and prod), even for "lookup" tables
For these reasons, coding literal IDs in queries is brittle.
Coding data literals like 'OPENED' and 'ONHOLD' is GOOD practice, because these values are going to be consistent across all servers and environments. If they do change, changing queries to be in sync will be part of the change script.
I assume that the question is about the two versions of the query -- one with the numeric comparison and the other with the join and string comparison.
Your colleagues are correct that the form with where thing_id in (list of ids) will perform better than the join. The difference in performance, however, might be quite minor if thing_id is not indexed. The query will already require a full table scan on the original table.
In most other respects, your version with the join is better. In particular, it makes the intent of the query cleaner and overall make the query more maintainable. For a small reference table, the performance hit may not be noticeable. In fact, in some databases, this form could be faster. This would occur when the in is evaluated as a series of or expressions. If the list is long, it might be faster to do an index lookup.
There is one downside to the join approach. If the values in the columns change, then the code also needs to be changed. I wouldn't be surprised if your colleague who suggests using primary keys has had this experience. S/he is working on an application and builds it using joins. Great. Lots of code. All clear. All maintainable. Then every week, the users decide to change the definitions of the codes. That can make almost any sane person prefer primary keys over using the reference table.
See Mark comment. I assume you are ok but can give my 2 cents on matter.
If that value is in the scope of one query I like to write that this, readable, way:
declare HOLD int = 4
SELECT <some fields>
FROM Thing
WHERE thing_type_id = HOLD
If that values are used many times in many points (queries, SP, views, etc)
I create a domain table.
create table ThingType (id int not null primary key, varchar(50) description)
GO
insert into ThingType values (4,'HOLD'),(5, 'ONHOLD')
GO
that way i can reuse that types on my selects as an enumerator
declare TYPE int
set TYPE = (select id from ThingType where description = 'HOLD')
SELECT <some fields>
FROM Thing
WHERE thing_type_id = TYPE
that way I keep meaning and performance (and also can enforce relational integrity over domain values)
Also I can just use enumerator at app level and just pass numeric values to the queries. A quick glimpse in that enumerator ill give me that number meaning.
In SQL queries you will definitely introduce a performance hit for JOINs (effectively multiple queries are taking place inside the SQL server). The question is whether the performance hit is significant enough to offset the benefits.
If it's just a readability thing then you may prefer to go for better performance and avoid the JOINs, but I would suggest you take into account potential integrity problems (e.g. what happens if the typed value of 4 in your example is changed by another process further down the line - the entire application may fail).
If the values will NEVER change then use PKs - this is a decision for you as the developer - there is no rule. One options may be best for one query and not for another.
In case of PL/SQL it makes sense to define constants in your package, e.g.
DECLARE
C_OPENED CONSTANT NUMBER := 3;
C_ONHOLD CONSTANT NUMBER := 4;
BEGIN
SELECT <some fields>
INTO ...
FROM Thing
WHERE thing_type_id in (C_OPENED, C_ONHOLD);
END;
Sometime it is usefull to create global package (without a body) where all commonly used constants are defined. In case the literal changes, you only have to modify the constant definition at a single place.

SQL Server - Select * vs Select Column in a Stored Procedure

In an ad-hoc query using Select ColumnName is better, but does it matter in a Stored Procedure after it's saved in the plan guide?
Always explicitly state the columns, even in a stored procedure. SELECT * is considered bad practice.
For instance you don't know the column order that will be returned, some applications may be relying on a specific column order.
I.e. the application code may look something like:
Id = Column[0]; // bad design
If you've used SELECT * ID may no longer be the first column and cause the application to crash. Also, if the database is modified and an additional 5 fields have been added you are returning additional fields that may not be relevant.
These topics always elicit blanket statements like ALWAYS do this or NEVER do that, but the reality is, like with most things it depends on the situation. I'll concede that it's typically good practice to list out columns, but whether or not it's bad practice to use SELECT * depends on the situation.
Consider a variety of tables that all have a common field or two, for example we have a number of tables that have different layouts, but they all have 'access_dt' and 'host_ip'. These tables aren't typically used together, but there are instances when suspicious activity prompts a full report of all activity. These aren't common, and they are manually reviewed, as such, they are well served by a stored procedure that generates a report by looping through every log table and using SELECT * leveraging the common fields between all tables.
It would be a waste of time to list out fields in this situation.
Again, I agree that it's typically good practice to list out fields, but it's not always bad practice to use SELECT *.
Edit: Tried to clarify example a bit.
It's a best practice in general but if you actually do need all the column, you'd better use the quickly read "SELECT *".
The important thing is to avoid retreiving data you don't need.
It is considered bad practice in situations like stored procedures when you are querying large datasets with table scans. You want to avoid using table scans because it causes a hit to the performance of the query. It's also a matter of readability.
SOme other food for thought. If your query has any joins at all you are returning data you don't need because the data in the join columns is the same. Further if the table is later changed to add some things you don't need (such as columns for audit purposes) you may be returning data to the user that they should not be seeing.
Nobody has mentioned the case when you need ALL columns from a table, even if the columns change, e.g. when archiving table rows as XML. I agree one should not use "SELECT *" as a replacement for "I need all the columns that currently exist in the table," just out of laziness or for readability. There needs to be a valid reason. It could be essential when one needs "all the columns that could exist in the table."
Also, how about when creating "wrapper" views for tables?

SQL: Using Select * [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Which is faster/best? SELECT * or SELECT column1, colum2, column3, etc.
Is it bad practice to use Select * ?
I was going through some old code and saw some 'SELECT *' statements. My previous coworker had told me Select * was bad practice, but I couldn't really see the reason why (unless of course I only needed to return a few fields). But for full 'detail retrieves' (Get by Id type queries) Select * seems right.
It's bad practice.
If your schema changes down the road, the calling application may get more fields than it knows what to do with.
Also, you are getting more info than you need, which affects performance.
Also also, it implies you don't know what the columns are.
Using SELECT * is bad practice for two reasons:
It can return extra columns that you don't need, wasting bandwidth
It can break your code if someone adds a column
Yes, Select * is a bad practice. For one, it is not clear to other developers which columns you really are using. Are you actually using all of them? What happens when you add columns are you using those too? That makes it much more difficult to refactor column names should that need arise. Second, there are some instances where some database systems will remember which columns existed at the time you created an object. For example, if you create a stored procedure with Select *, it will bake in the columns that exist in the table at the time it is compiled. If the table changes, it make not reflect those changes in the stored procedure. There really isn't any reason to use Select * beyond laziness.
Yes, it is deemed bad practice.
It is better to specify an explicit column list, especially if the table contains many columns and you only really need some of them.
If any schema changes occur (extra columns are added), these will be caught by your application. This might be undesirable, say, if you bind a grid dynamically to a DataTable. Also it incurs more overhead on network communications.
Even if you are selecting all columns as of today, define the columns by name - its readable and explicit. Any additional columns will then not cause any problems with your code.
When you use SELECT *, you choose to trade immediate productivity (writing a query faster) for potential maintenance productivity (should your underlying query change and thus break dependent code/queries). The "bad-ness" of the practice is a risk management activity.
Even if you need to select all columns it is still better to specify them rather then use 'select *'

Have any idea about to add column by stored procedure?

I want to add column to table by stored procedure and the name of column should be parameter.'s value.
You'll have to compose a dynamic DDL SQL statement where you concatenate the name of the column received as argument:
CREATE PROCEDURE AddColumnToTable
#columnName VARCHAR(128)
AS
EXEC ('ALTER TABLE tableName ADD' + SPACE(1) + #columnName + SPACE(1) + 'VARCHAR(MAX) NULL')
Note that in this example the name of the table as well as the column's type are hard-coded in the SQL statement. You may want to consider adding them as parameters to the stored procedure for a more generic solution.
Related resources:
Execute (Transact-SQL)
The Curse and Blessings of Dynamic SQL
This is a terrible idea in general. If your schema is requiring changes to tables that need to be done by sp, then they are happening too frequently and the design should be reviewed.
But if you are stuck with this horrible process (and I can't emphasize enough what a truly bad idea it is.) then you also need to have an input pvalue for the data type for the data as well and a nullable one for the size of the data type if need be, varchar(max) is a poor choice for every possible column to be added. It should only be used when you expect to have more than 8000 characters in the column for indexing reasons.
Why is this bad? Well to begin with, you have lost control over the schena. People can anything and there is no review to make sure you don't get twelve versions of the same things with slighly differnt names added. Next how do you intend to fix the application to use these fieldss without knowing what was added? Since you should never return more fields than you need, your production code should not be using select *. Therefore how do you know which fields to add if your users have added them. Users in general aren't knowledgeable enough to add fields. They don't understand database structure or design and don't understand how to normalize and performance tune. Letting people willy-nilly add fields to data tables is short-sighted and will lead to badly performing databases and awkward, hard-to-use interfaces that annoy the customers. If you have properly done your work in designing the database and application, there should be very little that a user needs to add. If you are basing your work on the user being able to have the flexibilty to add, you have a disaster of a project that not only will be hard to maintain, it will perform badly and in general your users will hate it. I've been forced to work work with some of these horrible commercial products (look at Clarity if you want an example of how flexibilty trumped design and made a product that is virtually unuseable).