How do I get MS LightSwitch to recognize my View? - sql-server

I've created a View from a table in another database. I have dbo rights to the databases so viewing and updating is not a problem. This particular View did not have an "id" column. So I added one to the View by using ROW_NUMBER. Now I had a problem with a table, in the same database, not showing up in LightSwitch but that was solved by changing the id column to be NOT NULL. I haven't done any real manipulation in LightSwitch. I'm still in the Import Your Data Source stage (ie. very beginning).
This View, in LightSwitch, is going to be read-only. No updating or deleting. From what I've read, LightSwitch needs a way to determine the PK of a Table or View. It either reads it from the schema (column set as a PK) or finds a column set as NOT NULL and uses that as the PK. Well I can't seem to do either of those things in SQL Server or LightSwitch, so I am stuck as to how to get LightSwitch to "see" my View.

for lightswitch to see your view you must have a primary key on a column of the table your are selecting from.
Example:
create table tbl_test
(
id int identity primary key not null,
value varchar(50)
)
create view vw_test
as
select *
from tbl_test
note:sometimes when you edit the primary key column in the view select statement it may cause lightswitch to not see it
Example:
create view vw_test
select cast(id as varchar(50) id,...
lightswitch would not see the table
Hope this was helpful! :)

What I do in this case is create a view with an ID column equal to the row number. Ensure the column you're basing the ID on is not null using the isnull() or coalesce() functions.
Example:
create view as
select distinct ID = row_number() over (order by isnull(Name,'')),
Name = isnull(Name,'')
from My_Table

Related

Any way to create function/method in SQL for combining columns in the SELECT?

Wrote a great simple function in SQL that apparently is not usable (or advisable) in my SELECT statement.
Have some intelligence behind combining Combinations of Company Name and Contact Name in our select and I find it's repeating across several views. Being a programmer, of course the right thing is to encapsulate that functionality for reuse across all views I'm created. But alas, from my searching it does not appear possible or recommended, at least not with UDFs.
The question: Is there any way to select the return value of a method/function/chunk of reusable code where I pass it the value of columns for each row... Or do I truly have to copy/paste the logic into each select statement?
SELECT formatName(company, contact, ' - ') as Name FROM company join contacts...
I know I can do this on the client (eventually), but client changes are not in scope for this phase of the project.
I guess I typed more in this question than just cutting and pasting a CASE statement into each view, but reuse is ingrained if me of course. :)
A better performing and DRY method to accomplish this is with a computed column.
A computed column is a virtual column that is not physically stored in
the table, unless the column is marked PERSISTED. A computed column
expression can use data from other columns to calculate a value for
the column to which it belongs. You can specify an expression for a
computed column in SQL Server 2017 by using SQL Server Management
Studio or Transact-SQL.
You can make this column persisted as well
PERSISTED Specifies that the Database Engine will physically store the
computed values in the table, and update the values when any other
columns on which the computed column depends are updated. Marking a
computed column as PERSISTED allows an index to be created on a
computed column that is deterministic, but not precise. For more
information, see Indexes on Computed Columns. Any computed columns
used as partitioning columns of a partitioned table must be explicitly
marked PERSISTED. computed_column_expression must be deterministic
when PERSISTED is specified.
alter table company add FullName as (FirstName + '-' + LastName) persisted;
Then, you could just add this column in your SELECT can can even query against it, if it's persisted.
What you can do is create a view that behaves like a table. Meaning it would have the performance of a table, can have indexes added etc. This view can have any of the columns of the underlying base table plus you can add calculated columns, such as [name]. This is accomplished by adding WITH SCHEMABINDING when creating the view. This view can then be used in lieu of the base table in all of your queries.
Here is an example.
The underlying base table with data:
CREATE TABLE dbo.company (
companyid int IDENTITY(1,1) NOT NULL,
company varchar(50) NULL,
contact varchar(50) NULL,
CONSTRAINT PK_company PRIMARY KEY CLUSTERED (companyid ASC)
) ON FG1
The view containing WITH SCHEMABINDING:
CREATE view dbo.VW_company WITH SCHEMABINDING AS
SELECT companyid,
CASE WHEN RTRIM(ISNULL(company,'')) <> '' AND RTRIM(ISNULL(contact,'')) <> '' THEN company +' - '+ contact
WHEN RTRIM(ISNULL(company,'')) <> '' THEN company
WHEN RTRIM(ISNULL(contact,'')) <> '' THEN contact
ELSE '' END as [Name]
FROM dbo.company
This view can now be used everywhere the table is used, without a performance hit. Furthermore, the calculated column [Name] can actually have an index added to it! That's something you cannot do with a function.

How does SQL Server Database Project: Publish decide when to recreate a table?

I have a SQL Server Database Project in which I've made several changes to the schema where I've changed column data types from NUMERIC (18,0) to INT. We're trying to normalize the data type used for Primary Keys, it's a currently 50/50 mix.
When I generate the Publish script, some of the tables are recreated in the script:
CREATE TABLE [dbo].[tmp_XYZ]
INSERT TABLE [dbo].[tmp_XYZ] SELECT ... FROM [dbo].[XYZ]
DROP TABLE [dbo].[XYZ]
sp_rename N'[dbo].[tmp_XYZ]', N'XYZ';
but other tables are just updated via ALTER statements
ALTER TABLE [dbo].[ABC] ALTER COLUMN [AbcID] INT NULL;
Is there some rule that dictates when a table will be recreated, and when it's just altered in place ?
Probably the best way is to Right Click on your object name and choose script as ...
Then you have options to create or alter
If you couldn't find Alter ,you can go to design view, right click and choose Generate Change Script ... to find the alter statement.
This is just an easy problem. It's the same problem as changing a table in the table designer. I think you've changed a column inside your table design which needs to drop and recreate the table to let the column order in the same position.
Here is a short example. Take this table design as given:
CREATE TABLE dbo.Test(
id int identity(1,1),
firstname nvarchar(100),
name nvarchar(100),
street nvarchar(100)
)
This will create the columns in a specified order. You can see this order here:
SELECT name, column_id
FROM sys.columns
WHERE object_id = OBJECT_ID(N'dbo.Test')
You'll see something like that:
column_name column_id
id 1
firstname 2
name 3
street 4
If you change the the column name via designer or in your case in the data project, this will cause SQL Server to obtain this order upright.
In this case you try to change the column name to lastname. This will enforce SQL Management Studio and other programs like that to keep the column_id upright. This can only be done, if the table is completely recreated with the right columnorder. SQL Server create a temporary table stub, insert everything into it, drop the old table and rename the temporary table to the old original name. Just as in your code above.
After that you'll see something like that:
column_name column_id
id 1
firstname 2
lastname 3
street 4
If you would simply rename the last column or do it manually, everything would be fine. Manually would be much more efficient, as there isn't the need to move ALL data to a new table. The manual way would be this:
-- Create the new column
ALTER TABLE dbo.Test ADD lastname nvarchar(100)
GO
-- Populate the new column using the old one
UPDATE dbo.Test
SET lastname = name
GO
-- Drop the old column afterwards
ALTER TABLE dbo.Test DROP COLUMN name
This behavior will result in the following result:
column_name column_id
id 1
firstname 2
street 4
lastname 5
The last one will be much more efficient, as already stated.
Hopefully this will answer your question, even if the answer comes lately.

How To change the column order of An Existing Table in SQL Server 2008

I have situation where I need to change the order of the columns/adding new columns for existing Table in SQL Server 2008.
Existing column
MemberName
MemberAddress
Member_ID(pk)
and I want this order
Member_ID(pk)
MemberName
MemberAddress
I got the answer for the same ,
Go on SQL Server → Tools → Options → Designers → Table and Database Designers and unselect Prevent saving changes that require table re-creation
2- Open table design view and that scroll your column up and down and save your changes.
It is not possible with ALTER statement. If you wish to have the columns in a specific order, you will have to create a newtable, use INSERT INTO newtable (col-x,col-a,col-b) SELECT col-x,col-a,col-b FROM oldtable to transfer the data from the oldtable to the newtable, delete the oldtable and rename the newtable to the oldtable name.
This is not necessarily recommended because it does not matter which order the columns are in the database table. When you use a SELECT statement, you can name the columns and have them returned to you in the order that you desire.
If your table doesn't have any records you can just drop then create your table.
If it has records you can do it using your SQL Server Management Studio.
Just click your table > right click > click Design then you can now arrange the order of the columns by dragging the fields on the order that you want then click save.
Best Regards
I tried this and dont see any way of doing it.
here is my approach for it.
Right click on table and Script table for Create and have this on
one of the SQL Query window,
EXEC sp_rename 'Employee', 'Employee1' -- Original table name is Employee
Execute the Employee create script, make sure you arrange the columns in the way you need.
INSERT INTO TABLE2 SELECT * FROM TABLE1.
-- Insert into Employee select Name, Company from Employee1
DROP table Employee1.
Relying on column order is generally a bad idea in SQL. SQL is based on Relational theory where order is never guaranteed - by design. You should treat all your columns and rows as having no order and then change your queries to provide the correct results:
For Columns:
Try not to use SELECT *, but instead specify the order of columns in the select list as in: SELECT Member_ID, MemberName, MemberAddress from TableName. This will guarantee order and will ease maintenance if columns get added.
For Rows:
Row order in your result set is only guaranteed if you specify the ORDER BY clause.
If no ORDER BY clause is specified the result set may differ as the Query Plan might differ or the database pages might have changed.
Hope this helps...
This can be an issue when using Source Control and automated deployments to a shared development environment. Where I work we have a very large sample DB on our development tier to work with (a subset of our production data).
Recently I did some work to remove one column from a table and then add some extra ones on the end. I then had to undo my column removal so I re-added it on the end which means the table and all references are correct in the environment but the Source Control automated deployment will no longer work because it complains about the table definition changing.
The real problem here is that the table + indexes are ~120GB and the environment only has ~60GB free so I'll need to either:
a) Rename the existing columns which are in the wrong order, add new columns in the right order, update the data then drop the old columns
OR
b) Rename the table, create a new table with the correct order, insert to the new table from the old and delete from the old as I go along
The SSMS/TFS Schema compare option of using a temp table won't work because there isn't enough room on disc to do it.
I'm not trying to say this is the best way to go about things or that column order really matters, just that I have a scenario where it is an issue and I'm sharing the options I've thought of to fix the issue
SQL query to change the id column into first:
ALTER TABLE `student` CHANGE `id` `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT FIRST;
or by using:
ALTER TABLE `student` CHANGE `id` `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT AFTER 'column_name'

Is there something like a "column symlink" in Oracle?

I would like to have a column in my DB accessible via two column names temporarily.
Why? The column name was badly chosen, I would like to refactor it. As I want my webapp to remain stable while changing the column name, it would be good to
have a (let's call it) symlink named better_column_name pointing to the column bad_column_name
change the webapplication to use better_column_name
drop the symlink and rename column to better_column_name
"Refactoring Databases" suggests to actually add a second column which is synchronized on commit in order to achieve this. I am just hoping that there might be an easier way with Oracle, with less work and less overhead.
As long as you have code that uses both column names, I don't see a way to get around the fact that you'll have two (real) columns in that table.
I would add the new column with the correct name and then create a trigger that checks which column has been modified and updates the "other" column correspondingly. So whatever is being updated, the value is synch'ed with the other column.
Once all the code that uses the old column has been migrated, remove the trigger and drop the old column.
Edit
The trigger would so do something like this:
CREATE OR REPLACE TRIGGER ...
...
UPDATE OF bad_column_name, better_column_name ON the_table
...
BEGIN
IF UPDATING ('BAD_COLUMN_NAME') THEN
:new.better_column_name = :new.bad_column_name
END IF;
IF UPDATING ('BETTER_COLUMN_NAME') THEN
:new.bad_column_name = :new.better_column_name
END IF;
END;
The order of the IF statements controls which change has a "higher priority" in case someone updated both columns at the same time.
Rename the table:
alter table mytable rename to mytable_old;
Create a view with the original tablename with both bad_column_name and better_column_name that point to the same column (and of course all the other columns):
create or replace view mytable as
select column1
, column2
, ...
, bad_column_name
, bad_column_name better_column_name
from mytable_old
;
Since this view is updatable by default (I assume here that mytable has a primary key), you can insert/update/delete from the view and it doesn't matter if you use bad_column_name or better_column_name.
After the refactoring, drop the view and rename the table and column:
drop view mytable;
alter table mytable_old rename column bad_column_name to better_column_name;
alter table mytable_old rename to mytable;
The best solution to this is only available in Oracle 11g Release 2: Edition-based Redefinition. This really cool feature allows us to maintain different versions of database tables and PL/SQL code, using special triggers and views. Find out more.
Essentially this is Oracle's built-in implementation of #AHorseWithNoName's suggestion.
you can create a view for the table. And port your application to use that view instead of the table.
create table t (bad_name varchar2(10), c2 varchar2(10));
create view vt as select bad_name AS good_name, c2 from t;
insert into vt (good_name, c2) values ('blub', 'blob');
select * from t;
select * from vt;
If you're on 11g you could look at using a virtual column. I'd probably be tempted to change the order slightly; rename the real column and create the virtual one using the old (bad) name, which can then be dropped at leisure. You may be restricted, of course, and there may be implications on other objects being invalidated that make this order less suitable for you.

Can you add identity to existing column in sql server 2008?

In all my searching I see that you essentially have to copy the existing table to a new table to chance to identity column for pre-2008, does this apply to 2008 also?
thanks.
most concise solution I have found so far:
CREATE TABLE Test
(
id int identity(1,1),
somecolumn varchar(10)
);
INSERT INTO Test VALUES ('Hello');
INSERT INTO Test VALUES ('World');
-- copy the table. use same schema, but no identity
CREATE TABLE Test2
(
id int NOT NULL,
somecolumn varchar(10)
);
ALTER TABLE Test SWITCH TO Test2;
-- drop the original (now empty) table
DROP TABLE Test;
-- rename new table to old table's name
EXEC sp_rename 'Test2','Test';
-- see same records
SELECT * FROM Test;
we cannot add identity to an existing column using sql command but we can do it using GUI.
Right click on the table - design - select the column on which you want to add identity.
go to the properties available below. find the identity specification and set it to yes.
save the table.
if it is not saved the go to tools from the menu - options - table designer - uncheck the checkbox prevent saving changes. now you can save the table modifications.
now your existing table had identity.
In all of the new feature documents I read about 2008, adding identity to an existing column was not a feature I recall. The solution you've found is correct and I think the process of adding identity increment to a column automatically would be only rarely useful.
Well you can do something like this.
ALTER TABLE my_table ADD ID_COLUMN INT IDENTITY (1,1) NOT NULL
You can add the IDENTITY property to an existing column using the GUI of Enterprise Manager / Management Studio.
In SQL 2005 and earlier, you could not modify an existing column to become an identity column. I deem it very very unlikely that MS changed that in 2008.

Resources