SQL Server view columns have wrong case - sql-server

I have a table I am trying to create a view of to work with a new reporting application that needs specific columns. I would think this should be straightforward, but the column names are in the wrong case. Specifically, one column is Customer_ID instead of changing to customer_id as specified in the SQL statement used to create the view.
The original table is: Customer_ID | CustomerAddress | CustomerPhone
The view needs to be: customer_id | customer_address | customer_phone
The view is: Customer_ID | customer_address | customer_phone
The command to create the view is:
BEGIN
SET NOCOUNT ON;
DECLARE #sql_customers nvarchar(max) = 'CREATE VIEW customers AS SELECT
oldcustomers.Customer_ID as customer_id,
oldcustomers.CustomerAddress as customer_address,
oldcustomers.CustomerPhone as customer_phone
FROM oldcustomers'
EXECUTE sp_executesql #sql_customers
END

There's no need to use aliases to change the case unless you're using a case sensitive collation.
The following should do the trick w/o having to jump through hoops...
CREATE VIEW customers
AS
SELECT
oc.customer_id,
oc.customeraddress,
oc.customerphone
FROM
dbo.oldcustomers oc;

Related

How to efficiently replace long strings by their index for SQL Server inserts?

I have a very large DataTable-Object which I need to import from a client into an MS SQL-Server database via ODBC.
The original Data-Table has two columns:
* First column is the Office Location (quite a long string)
* Second column is a booking value (integer)
Now I am looking for the most efficient way to insert these data into an external SQL-Server. My goal is to replace each office location automatically by an index instead using the full string because each location occurs VERY often in the initial table.
Is this possible via a trigger or via a view on the SQL-server?
At the end I want to insert the data without touching them in my script because this is very slow for these large amount of data and let the optimization done by the SQL Server.
I expect that if I do INSERT the data including the Office location, that SQL Server looks up an index for an already imported location and then use just this index. And if the location did not already exist in the index table / view then it should create a new entry here and then use the new index.
Here a sample of the data I need to import via ODBC into the SQL-Server:
OfficeLocation | BookingValue
EU-Germany-Hamburg-Ostend1 | 12
EU-Germany-Hamburg-Ostend1 | 23
EU-Germany-Hamburg-Ostend1 | 34
EU-France-Paris-Eifeltower | 42
EU-France-Paris-Eifeltower | 53
EU-France-Paris-Eifeltower | 12
What I do need on the SQL-Server is something like these 2 tables as a result:
OId|BookingValue OfficeLocation |Oid
1|12 EU-Germany-Hamburg-Ostend1 | 1
1|23 EU-France-Paris-Eifeltower | 2
1|43
2|42
2|53
2|12
My initial idea was, to write the data into a temp-table and have something like an intelligent TRIGGER (or a VIEW?) to react on any INSERT into this table to create the 2 desired (optimized) tables.
Any hint are more than welcome!
Yes, you can create a view with an INSERT trigger to handle this. Something like:
CREATE TABLE dbo.Locations (
OId int IDENTITY(1,1) not null PRIMARY KEY,
OfficeLocation varchar(500) not null UNIQUE
)
GO
CREATE TABLE dbo.Bookings (
OId int not null,
BookingValue int not null
)
GO
CREATE VIEW dbo.CombinedBookings
WITH SCHEMABINDING
AS
SELECT
OfficeLocation,
BookingValue
FROM
dbo.Bookings b
INNER JOIN
dbo.Locations l
ON
b.OId = l.OId
GO
CREATE TRIGGER CombinedBookings_Insert
ON dbo.CombinedBookings
INSTEAD OF INSERT
AS
INSERT INTO Locations (OfficeLocation)
SELECT OfficeLocation
FROM inserted where OfficeLocation not in (select OfficeLocation from Locations)
INSERT INTO Bookings (OId,BookingValue)
SELECT OId, BookingValue
FROM
inserted i
INNER JOIN
Locations l
ON
i.OfficeLocation = l.OfficeLocation
As you can see, we first add to the locations table any missing locations and then populate the bookings table.
A similar trigger can cope with Updates. I'd generally let the Locations table just grow and not attempt to clean it up (for no longer referenced locations) with triggers. If growth is a concern, a periodic job will usually be good enough.
Be aware that some tools (such as bulk inserts) may not invoke triggers, so those will not be usable with the above view.

How to add data to a single column

I have a question in regards to adding data to a particular column of a table, i had a post yesterday where a user guided me (thanks for that) to what i needed and said an update was the way to go for what i need, but i still can't achieve my goal.
i have two tables, the tables where the information will be added from and the table where the information will be added to, here is an example:
source_table (has only a column called "name_expedient_reviser" that is nvarchar(50))
name_expedient_reviser
kim
randy
phil
cathy
josh
etc.
on the other hand i have the destination table, this one has two columns, one with the ids and the other where the names will be inserted, this column values are null, there are some ids that are going to be used for this.
this is how the other table looks like
dbo_expedient_reviser (has 2 columns, unique_reviser_code numeric PK NOT AI, and name_expedient_reviser who are the users who check expedients this one is set as nvarchar(50)) also this is the way this table is now:
dbo_expedient_reviser
unique_reviser_code | name_expedient_reviser
1 | NULL
2 | NULL
3 | NULL
4 | NULL
5 | NULL
6 | NULL
what i need is the information of the source_table to be inserted into the row name_expedient_reviser, so the result should look like this
dbo_expedient_reviser
unique_reviser_code | name_expedient_reviser
1 | kim
2 | randy
3 | phil
4 | cathy
5 | josh
6 | etc.
how can i pass the information into this table? what do i have to do?.
EDIT
the query i saw that should have worked doesn't update which is this one:
UPDATE dbo_expedient_reviser
SET dbo_expedient_reviser.name_expedient_reviser = source_table.name_expedient_reviser
FROM source_table
JOIN dbo_expedient_reviser ON source_table.name_expedient_reviser = dbo_expedient_reviser.name_expedient_reviser
WHERE dbo_expedient_reviser.name_expedient_reviser IS NULL
the query was supposed to update the information into the table, extracting it from the source_table as long as the row name_expedient_reviser is null which it is but is doesn't work.
Since the Names do not have an Id associated with them I would just use ROW_NUMBER and join on ROW_NUMBER = unique_reviser_code. The only problem is, knowing what rows are null. From what I see, they all appear null. In your data, is this the case or are there names sporadically in the table like 5,17,29...etc? If the name_expedient_reviser is empty in dbo_expedient_reviser you could also truncate the table and insert values directly. Hopefully that unique_reviser_code isn't already linked to other things.
WITH CTE (name_expedient_reviser, unique_reviser_code)
AS
(
SELECT name_expedient_reviser
,ROW_NUMBER() OVER (ORDER BY name_expedient_reviser)
FROM source_table
)
UPDATE er
SET er.name_expedient_reviser = cte.name_expedient_reviser
FROM dbo_expedient_reviser er
JOIN CTE on cte.unique_reviser_code = er.unique_reviser_code
Or Truncate:
Truncate Table dbo_expedient_reviser
INSERT INTO dbo_expedient_reviser (name_expedient_reviser, unique_reviser_code)
SELECT DISTINCT
unique_reviser_code = ROW_NUMBER() OVER (ORDER BY name_expedient_reviser)
,name_expedient_reviser
FROM source_table
it is not posible to INSERT the data into a single column, but to UPDATE and move the data you want is the only way to go in that cases

Stored procedure to create or update

I am working on creating a Web API which will get account as the input parameter, which will have to create / update records in the table in SQL Server. So the web service will need to call the stored procedure which will accept the account. I created a sample table in the database with just two columns called Account and CounterSeq. I am trying to creating a stored procedure to create or update the records in the table.
Each account should have a CounterSeq associated with it. If the Account doesn't exists in the table, create Account name and associate CounterSeq = 001 to it. If the Account name already exists, just update like CounterSeq to CounterSeq + 1
+---------+----------------+
| Account | CounterSeq |
+---------+----------------+
| ABC | 001 |
| DEF | 002 |
+---------+----------------+
For this I create a TableType like this
USE [Demo]
GO
-- Create the data type
CREATE TYPE projectName_TT AS TABLE
(
Account nvarchar(50),
CounterSeq int
)
GO
And the stored procedure as below but I am missing how to insert the new record like for a new Account how to set the CounterSeq to 001 ?
USE [Demo]
GO
ALTER PROCEDURE [dbo].[uspInserorUpdateProjectName]
#projectName_TT AS projectName_TT READONLY
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRANSACTION;
UPDATE prj
SET prj.Account = tt.Account,
prj.CounterSeq = tt.CounterSeq + 1
FROM dbo.[ProjectName] prj
INNER JOIN #projectName_TT tt ON prj.Account = tt.Account
INSERT INTO [dbo].[ProjectName](Account, CounterSeq)
SELECT tt.Account, tt.CounterSeq
FROM #projectName_TT tt
WHERE NOT EXISTS (SELECT 1
FROM [dbo].[ProjectName]
WHERE Account = tt.Account)
COMMIT TRANSACTION;
END;
First, I believe that the table you passed in should only have one field (based on your description If the Account doesn't exists in the Database create Account name and associate CounterSeq 001 to it. If the Account name already exists just update like CounterSeq to CounterSeq+1)
You can use this query (put it in your stored procedure between the BEGIN TRANSACTION, COMMIT TRANSACTION.
MERGE dbo.[ProjectName] prj
USING #projectName_TT tt
ON prj.Account = tt.Account
WHEN MATCHED THEN UPDATE SET prj.CounterSeq = prj.CounterSeq+1
WHEN NOT MATCHED THEN INSERT (Account,CounterSeq)
VALUES (tt.Account, 1);

SQL Script: Updating a column with another table pivoting on an ID

I have two SQL Server tables: ORDERS and DELIVERIES.
I would like to update the ORDERS table with a value from DELIVERIES. The ORDERS PK (OrderID) is common to both tables. Also, I would like to restrict the action to a specific CustomerID (within ORDERS).
ORDERS table:
OrderID | AccountID | AnalysisField1
DELIVERIES table:
DeliveryID | OrderID | AddressName
I want to update ORDERS.AnalysisField1 with the value from DELIVERIES.AddressName (linked by OrderID) but only where ORDERS.AccountID = '12345'
Please help. JM
Then try to use something like this:
UPDATE dbo.Orders
SET AnalysisField1 = d.Addressname
FROM dbo.Deliveries d
WHERE
d.OrderID = dbo.Orders.OrderID
AND dbo.Orders.AccountID = '12345'
If your AccountID column is of a numerical type (which the ID suffix would suggest), then you should not put unnecessary single quotes around the value in the WHERE clause:
AND dbo.Orders.AccountID = 12345

SQL View where rows not mapped

Basically what I'm trying to figure out is,
Say I have
table 1tbl1
ID | Name
and table2tbl2
ID | Name
Then I have a mapping table mt
ID | tbl1ID | tbl2ID
Data really isn't important here, and these tables are examples.
How to make a view that will grab all the items in tbl1 that aren't mapped to mt.
I'm using Microsoft SQL-server 2008 by the way.
CREATE VIEW v_unmapped
AS
SELECT *
FROM tbl1
WHERE id NOT IN
(
SELECT tbl1Id
FROM mt
)

Resources