1

EDIT: I tried this code, part of what a user mentioned, and it returns the fields correctly.

SELECT * FROM INFORMATION_SCHEMA.TABLES 
        JOIN INFORMATION_SCHEMA.COLUMNS on 
        INFORMATION_SCHEMA.TABLES.TABLE_NAME = 
        INFORMATION_SCHEMA.COLUMNS.TABLE_NAME
WHERE INFORMATION_SCHEMA.TABLES.TABLE_NAME = 'myTable'

There is something in the former query that works with some databases but not with others


EDIT2:

I've tried setting up a Profiler trace to check the columns creation through the wizard, as a user suggested. It is using the same schema, apparently.

ALTER TABLE dbo.table1 ADD
field2 nchar(10) NULL

I'm working with SQL Server 2014, and created databases by using the wizard, I mean, not by code, but by using the UI.

Then, I tried to fetch metadata information as regards their tables' columns.. and no results are returned. I query INFORMATION_SCHEMA.

I've tried using the same query for databases I've created by code, and it works fine, it returns the columns and their values, etc.

I've tried looking it up over the internet, but can't seem to think anything that fits cases like these. I think it's a bit weird that it makes a difference with columns created by code and through the UI.. If anyone knows why something like this can happen, or seems familiar, I would appreciate some light on it :)

Here's the code I use to retrieve the columns' metadata:

USE 'database'
SELECT infSch.TABLE_CATALOG,
       infSch.TABLE_NAME,
       sysCols.name,
       infSch.ORDINAL_POSITION,
       sysCols.is_nullable,
       infSch.DATA_TYPE,
       infSch.CHARACTER_MAXIMUM_LENGTH,
       sysCols.is_identity,
       IIF(infSchCons.CONSTRAINT_TYPE = 'PRIMARY KEY', 1, 0),
       IIF(infSchCons.CONSTRAINT_TYPE = 'FOREIGN KEY', 1, 0),
       IIF(infSchCons.CONSTRAINT_TYPE = 'UNIQUE', 1, 0),
       IIF(infSchCons.CONSTRAINT_TYPE = 'CHECK', 1, 0)
FROM sys.columns as sysCols 
RIGHT JOIN INFORMATION_SCHEMA.COLUMNS as infSch on sysCols.name = 
     infSch.COLUMN_NAME
RIGHT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS as infSchCons on 
     infSch.TABLE_NAME = infSchCons.TABLE_NAME

Results:

  • If table and columns were created by code --> it returns all the columns and its metadata, for a given database

  • If table and columns were created by using the UI and windows --> it returns nothing, just an empty set of results

xragdollqueen
  • 113
  • 4
  • 14
  • 1
    Probably a useless question, but are you certain that the connection to the server and database you used in your Sql client (SSMS?) to run that query is the same as the one used by your UI to create the table? – LukStorms Dec 09 '18 at 21:29
  • @LukStorms yes, it's the same one apparently, as far as I can see; also if I do a simple SELECT * FROM myTable, it works as expected, the columns are there, but it looks as if they weren't part of the INFORMATION_SCHEMA views :s – xragdollqueen Dec 09 '18 at 21:53
  • It'll definitely be in the system tabkes; at the end of the day all the wizard does is run T-SQL. If it is not in the query you're running you're looking in the wrong place, or one of your constraints is removing the object from your `SELECT`. – Thom A Dec 09 '18 at 21:58
  • 1
    Just to check if it's due to something in the query, does `select * from information_schema.tables where table_name = 'myTable'` give you any result? (obviously replace 'myTable' with your table name) – LukStorms Dec 09 '18 at 22:02
  • @LukStorms mmm weird.. I executed the query you mentioned and it returns as expected. I added the columns, and it returns just fine. There must be something in the query that works for some databases, but not for others – xragdollqueen Dec 09 '18 at 22:30
  • 2
    I suspect the reason is your table has no contraints. – Thom A Dec 09 '18 at 22:35
  • Well I guess that if the table doesn't have constraints and you add a criteria like `WHERE infSchCons.TABLE_NAME = 'myTable'` would be a dud. – LukStorms Dec 09 '18 at 22:55
  • 1
    Set up a Profiler trace and check the code executed by the wizard. Quite possible it creates objects in a schema other than `dbo`, and / or you don't have full permissions in these databases to see everything. – Roger Wolf Dec 09 '18 at 23:15
  • @RogerWolf First time setting a Profiler trace; I've checked and it is using the same schema, `dbo`. Anyway, thanks for the suggestion :) – xragdollqueen Dec 09 '18 at 23:38
  • it is related to having no constraints, note that the right joins alter the priority of tables – Paul Maxwell Dec 10 '18 at 00:52

1 Answers1

2

Right joins change the nature of the query, and they can always be re-written by reversing the order of tables. Avoid the right joins.... try this instead:

SELECT infSch.TABLE_CATALOG,
       infSch.TABLE_NAME,
       sysCols.name,
       infSch.ORDINAL_POSITION,
       sysCols.is_nullable,
       infSch.DATA_TYPE,
       infSch.CHARACTER_MAXIMUM_LENGTH,
       sysCols.is_identity,
       IIF(infSchCons.CONSTRAINT_TYPE = 'PRIMARY KEY', 1, 0),
       IIF(infSchCons.CONSTRAINT_TYPE = 'FOREIGN KEY', 1, 0),
       IIF(infSchCons.CONSTRAINT_TYPE = 'UNIQUE', 1, 0),
       IIF(infSchCons.CONSTRAINT_TYPE = 'CHECK', 1, 0)
FROM sys.columns as sysCols 
LEFT JOIN INFORMATION_SCHEMA.COLUMNS as infSch on sysCols.name = 
     infSch.COLUMN_NAME
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS as infSchCons on 
     infSch.TABLE_NAME = infSchCons.TABLE_NAME

That query does NOT limit results to only those where constraints exist.

Try comparing these:

select count(*) from (

    SELECT
        infSchCons.*
    FROM sys.columns as sysCols 
    right JOIN INFORMATION_SCHEMA.COLUMNS as infSch on sysCols.name = infSch.COLUMN_NAME
    right JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS as infSchCons on infSch.TABLE_NAME = infSchCons.TABLE_NAME

    ) x
;

select count(*) from (

    SELECT
        infSchCons.*
    FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS infSchCons
    left JOIN INFORMATION_SCHEMA.COLUMNS AS infSch ON infSchCons.TABLE_NAME = infSch.TABLE_NAME
    left JOIN sys.columns AS sysCols ON infSch.COLUMN_NAME = sysCols.name

    ) x
;

The last query is a re-write of the original from clause, and here it is easier (in my view) to see that you must have constraints for any row to be returned.


EDIT

The question asked why a particular query did not work in some databases.

That query uses RIGHT OUTER JOINS

Due to the way that join tyupe operates it alters the priority of tables - and this can be confusing

Because all right joins can be "reversed", when you do the the equivalent query (to the original) has a from clause like this:

FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS infSchCons
left JOIN INFORMATION_SCHEMA.COLUMNS AS infSch ON infSchCons.TABLE_NAME = infSch.TABLE_NAME
left JOIN sys.columns AS sysCols ON infSch.COLUMN_NAME = sysCols.name

So the table with the highest priority is INFORMATION_SCHEMA.TABLE_CONSTRAINTS and if there are no rows in that table, the query will not return any data.

In the second edit to the question there is a query that works:

SELECT
    *
FROM INFORMATION_SCHEMA.TABLES
JOIN INFORMATION_SCHEMA.COLUMNS ON INFORMATION_SCHEMA.TABLES.TABLE_NAME =
    INFORMATION_SCHEMA.COLUMNS.TABLE_NAME
WHERE INFORMATION_SCHEMA.TABLES.TABLE_NAME = 'myTable'

And: this "works" because the table with the highest priority is INFORMATION_SCHEMA.TABLES which is almost guaranteed to have rows in it.

So, the original query uses the wrong highest priority table, which is obscured due to the right joins. The query that works uses a sensible table as its base table, and does not use right joins.

Paul Maxwell
  • 33,002
  • 3
  • 32
  • 51
  • hi! Thanks, but the first query returns lost of NULL in the database name (even while selecting a specific database to work on) and if I use `JOIN` it returns nothing. And zero results for the comparison queries you send me to check what was going on. STILL, all of that DOES work fine with databases created through code :/ is there any possibility of differences between the databases form of creation and how they are read? it seems improbable to me, but it cannot think of anything else after checking the constraints in the queries :s – xragdollqueen Dec 13 '18 at 15:49
  • 1
    I was not proposing a "better" query, you asked why it behaved strangely, which is due to the right joins. So simply changing to join type the query does operate highlighting the cause of the initial problem. – Paul Maxwell Dec 13 '18 at 20:59
  • 1
    I have added more explanation to my answer, perhaps this makes it clear? – Paul Maxwell Dec 13 '18 at 21:42
  • hi! It definitely helped. I was very puzzled at that moment, sorry for the late reply. It still is a _bit_ weird, but now I get how the constraints where making it behave in that certain way. Thank you so much for taking the time to clarify :) – xragdollqueen Feb 03 '19 at 19:09