I am learning how to use SQL server recently. I do not understand why use master..sysdatabases and test..sysobjects in the following statements:
select name from [master]..[sysdatabases] where dbid=1;
select count(1) from [test]..[sysobjects] where xtype = 'U';
What does the 1 in count(1) mean? Does it mean the first column?
Thanks for any helpful answers.
Your first line basically gets the name of the master database (it looks at the list of all databases, and returns the name of the database with the ID of 1, which in this case is generally going to be 'master').
Do a to see all the databases on a server:
SELECT * FROM [master]..[sysdatabases]
Note that the row with "dbid" = 1, is the row for the "master" database, which is a system database present on all SQL Server instances.
Your second line counts the number of rows in the sysobjects collection in the database named 'test' where the type is a user table (i.e. not a stored procedure, not a system table, etc).
In the expression "[x]..[y]", the 'x' is the name of the database, and 'y' is the name of the table or view within that database.
If you had a database named "Foo", and in there was a table named "Bar", then this statement would return the count of rows in that table:
SELECT COUNT(1) FROM [Foo]..[Bar]
As Ed Gibbs above described, the '1' is just a place-holder for counting the total number of rows in the most efficient way possible on any possible database or version. It's become a sort of short-hand way of counting.
Related
Result is fetching zero records.
enter image description here
Are you connected to (logged into) the database in which that table exists?
SQL such as this would be a starting point
select * from _v_relation_column
where UPPER(name) = 'MY_TABLE'
and UPPER(schema) = 'MY_SCHEMA'
order by attnum;
The restriction on schema may not be needed (if you aren't using multiple schemas).
(A) Sometimes we need the column names as headers
select * from <table> limit 0
(B) If you want definition of a table ie. showing all columns along with their data types etc (assuming you have nzsql cli)
nzsql <db> -c "\d <table>"
In Dataverse if I create a table e.g 'foo' MS Dynamics automatically pre-fixes my tables with a few characters to denote that they are my custom tables e.g. abcd_foo.
What's more, if connect to the database with SSMS I can query the table as follows:
Select * from abcd_foo;
When you create a Choice column in foo, the table contains an integer value that references the lookup value - not the lookup value itself.
The picture below shows the choice values returned from a query:
Select
abcd_accesslevel -- my choice column
from abcd_foo;
What is the name of the SQL Table in which MS Dynamics stores these 'choice values' which it then internally joins up to my tables foo choice column, acceslevel?
e.g. if 'abcd_accesslevel' is a Choice column, how would I complete this query:
Select f.abcd_accesslevel,
c.label, -- The choice label
c.value, -- The choice value
f.*
from abcd_foo f
left join some_internal_choice_table c on c.someid = f.abcd_accesslevel
-- There may be a more complex WHERE clause to separate out the label for my table from the other choice values if all choices are stored in a common table.
In Dataverse there are 2 optionsets, local and global.
In your case I believe your abcd_accesslevel is local optionset.
local optionset is stored in metadata Entitydefinitions.
I never retrieved this via sql but I user API to fetch such data.
example API call
https://XYZ.crm.dynamics.com/api/data/v9.2/EntityDefinitions(LogicalName=’incident’)/Attributes/Microsoft.Dynamics.CRM.PicklistAttributeMetadata?&$expand=OptionSet
I tried this sql query and worked for me. (I tried on my account entity)
SELECT *
FROM stringmap
WHERE objecttypecode = 'abcd_foo'
AND attributename = 'abcd_accesslevel ';
I'm trying to insert daily imported data into a SQL Server (2017) table. While most of the time the imported data has a fixed amount of columns, sometimes the client wants to add a new column to the data-to-be-imported.
I'm seeking for a solution that when the data gets imported (whether it is from another table, from R or from .csv's, don't mind this), SQL would automatically add the missing (extra) column to the parent table, providing the column name and assigning NULL to all previous entries.
I've tried with both UNION ALL and BULK INSERT, but both of these require the same # of columns. I'm working with SSMS2017, R3.4.1.
Next, I tried with a staging table and modifying the UNION clause as:
SELECT * FROM Table_new
UNION ALL
SELECT Tp.*, '' FROM Table_parent Tp;
But more often than not the extra column doesn't occur, so the column dimension problem occurs again.
I also thought about running the queries from R with DBI and odbc dbWriteTable() and handling the invalid column error with TryCatch(), parsing the column name from the error message and so on, but this would be a shakiest craft I've ever done and would prefer not to.
Ultimately I thought adding an if clause in R, and depending on the number of added new columns, loop and add the ', ""' part to the SQL query to create the extra columns. I'm convinced that this is too complex solution to this problem.
# Pseudo-R
#calculate the difference between lenght(colnames)
diff <- diff(length(colnames_new, colnames_parent)
if diff = 0 {
dbQuery(BULK INSERT INTO old SELECT * FROM new;)
} else if diff > 0 {
dbQuery(paste0(SELECT * FROM new
UNION ALL
SELECT T1.*, loop_paste(, '' /* for every diff */), FROM parent T1;))
} else if diff < 0 {
dbQuery(SELECT * FROM parent
UNION ALL
SELECT T2.*, loop_paste(, '' /* for every diff */), FROM new T2;))
}
To summarize: when inserting data to SQL table, how to (automatically) append the columns in the parent table, when necessary? Thanks!
The things in your database such as tables, columns, primary keys, foreign keys, check clauses are all part of the database schema. People design the schema before adding data to the database.
If you want to add new columns then you have to redesign your schema. When you do this you will also have to rewrite some of the CRUD procedures.
I have 2 tables in 2 database. The scheme for the tables is identical. There are no timestamps or last updated information. Table A is a live table, that is, it's updated in "the" program. Update records, insert records and delete records all happen in Table A. Table B is a backup made weekly. Is there a quick way to compare the 2 tables and give me results similar to:
I | 54
D | 55
U | 60
So record 54 in the live table is new, record 55 in the live table was deleted, record 60 in the live table was updated.
This needs to work in SQL Server 2008 and up.
Fields: id, first_name, last_name, phone, email, address_id, birth_date, last_visit, provider_id, comments
I have no control over the scheme. I have read-only access to Table A, read-write to Table B.
Would it be easier to store a hash of each Table A's rows rather than a full copy of the table? Generally speaking I need to know what rows have been updated/inserted and deleted without a build in timestamp. I have the weekly backup table to look at but I could create a hash table if needed.
Using two full joins the first one isvused to check just for id existance and identify inserts and deletes the second would be used for row equality.
In the example I have used checksum for simplicity but I recommend you read up on the cons of using it and consider alternatives like hashbytes or checking each column for equality
Select id, checksum(*) hash
Into #live
From live.dbo.tbl
Select id, checksum(*) hash
Into #archive
From archive.dbo.tbl
Select l1.id,
Case when l1.id is null then 'd'
when a1.id is null then 'I'
when a2.id is null then 'u' end change_type
From #live l1
Full Join #archive a1 On a1.id = l1.id
Full Join #archive a2 On a2.id = l1.id
And a2.hash = l1.hash
I'm going to recommend a tool, but it's not free, although it has a fully functioning 30 day trial period. If you're going to compare data in SQL Server tables, look at Red Gate's SQL Data Compare. It's not cheap, and it will pay for itself many times over. (If you need to compare schemas, their SQL Compare does that.)
Barring that, having a third table, where you write a compare query and select those in one table and not the other (with a field indicating that), those in the other table and not the first, and then comparing field by field to find those different -- well that should work too. It will take longer, but if it's just one one table, the time it takes to write that code should be less than what you'll pay for the Red Gate tools.
If there is a column or set of columns that can uniquely identify each row, then a series of sql statements could be written to identify the inserts, updates and deletes. If there isn't a unique row identifier or the unique identifier (for example, one of the columns that makes it unique) changes, then no.
I am very new to SQL and SQL server, would appreciate any help with the following problem.
I am trying to update a share price table with new prices.
The table has three columns: share code, date, price.
The share code + date = PK
As you can imagine, if you have thousands of share codes and 10 years' data for each, the table can get very big. So I have created a separate table called a share ID table, and use a share ID instead in the first table (I was reliably informed this would speed up the query, as searching by integer is faster than string).
So, to summarise, I have two tables as follows:
Table 1 = Share_code_ID (int), Date, Price
Table 2 = Share_code_ID (int), Share_name (string)
So let's say I want to update the table/s with today's price for share ZZZ. I need to:
Look for the Share_code_ID corresponding to 'ZZZ' in table 2
If it is found, update table 1 with the new price for that date, using the Share_code_ID I just found
If the Share_code_ID is not found, update both tables
Let's ignore for now how the Share_code_ID is generated for a new code, I'll worry about that later.
I'm trying to use a merge query loosely based on the following structure, but have no idea what I am doing:
MERGE INTO [Table 1]
USING (VALUES (1,23-May-2013,1000)) AS SOURCE (Share_code_ID,Date,Price)
{ SEEMS LIKE THERE SHOULD BE AN INNER JOIN HERE OR SOMETHING }
ON Table 2 = 'ZZZ'
WHEN MATCHED THEN UPDATE SET Table 1.Price = 1000
WHEN NOT MATCHED THEN INSERT { TO BOTH TABLES }
Any help would be appreciated.
http://msdn.microsoft.com/library/bb510625(v=sql.100).aspx
You use Table1 for target table and Table2 for source table
You want to do action, when given ID is not found in Table2 - in the source table
In the documentation, that you had read already, that corresponds to the clause
WHEN NOT MATCHED BY SOURCE ... THEN <merge_matched>
and the latter corresponds to
<merge_matched>::=
{ UPDATE SET <set_clause> | DELETE }
Ergo, you cannot insert into source-table there.
You could use triggers for auto-insertion, when you insert something in Table1, but that will not be able to insert proper Shared_Name - trigger just won't know it.
So you have two options i guess.
1) make T-SQL code block - look for Stored Procedures. I think there also is a construct to execute anonymous code block in MS SQ, like EXECUTE BLOCK command in Firebird SQL Server, but i don't know it for sure.
2) create updatable SQL VIEW, joining Table1 and Table2 to show last most current date, so that when you insert a row in this view the view's on-insert trigger would actually insert rows to both tables. And when you would update the data in the view, the on-update trigger would modify the data.