While working with DB, I find useful using some tools, that help me to solve DB problems.
Some of them are:
1) Insert generator
2) A tool that can execute a script on a list of DB's
3) Finding a text in stored procedures and functions.
4) DB Back up scripts
My question is, what are most useful tools, scripts(anything else), that help you to work with SQL Server?
Thanks in advance.
UPDATE
I assume, there are no other tools for SQL Server 2008 or any other version?
Redgate has a collection of quite powerful tools for Sql Server.
Check out the SMSS Tools Pack.
I have stored procedures that do the following:
system utilities:
find and list every occurrence and info about a given column name or partial column name
find and list every occurrence and info about a given object name or partial object name
list out all the information for a given table, all columns, computed columns, column data types, nullability, defaults, identity, check constraints, index, pk, fk, triggers, and column comments.
find every trigger, view, stored procedure, or function that contains a given string
business utilities:
I also make stored procedures that work with business info. When working on an area of our application I'll make a procedure that displays out all the related info of a given thing. I'll usually display all the info using multiple PRINTs and SELECTs for everything that can join to the given PK (not if there are thousands or rows though). For example, one utiltiy would take a DoctorID as a parameter and list out all the doctor's info, offices that they work at, insurance they accept, etc. I like to include the table names in the output so I can remember where the data comes from without looking at the code. I also join in all the codes tables in these displays, so I'm not looking "A" but "Active (A)". After working on a system for a while, I have loads of these utilities, which greatly helps when a support call comes up or you need to debug a problem, etc. I usually build these as I develop, it is difficult to find time to go back and make them.
Related
Hello helpful internet strangers. I have created a fairly simple database for a client that has one main entry form and a search form that uses unbound text boxes for searching around 15 fields.
Details are below, but here is my problem: When I add new records and use the search form all the fields work as expected and return the correct results in the datasheet. When I sent the database to the client and they add new records, they are not returned in the search. I had them save the database with their records and send it back to me, and I confirmed that when I search for the records they added (I can see the records in the table) they are not returned in the search. If I add new records to the copy they sent me back, my records do appear in the search.
I created the database in Access 2013 on a Windows 8 machine. The client is using Access 2010 on Windows Vista.
The field types are text, dropdown and date. The dropdowns are all based on lookup queries so they store the id number in the main info table and pull the name value from the query. All of the fields in the search query are written to allow nulls, including the date range searches. And again, all fields test out correctly on my machine when I enter the records.
I went on site and compared settings and nothing jumped out at me except the different versions. I also watched the client enter new records and she didn't do anything 'wrong' or unusual. When I try to do a save as 2007-2010 it says I am using features that won't allow for that, but for the life of me I can't think of anything like that since this is really a very straightforward design.
I'm going to do a package as executable, but am highly doubtful that will help. Any insights?
Thanks in advance.
A few things. Most important - always, always develop in the earliest version of Access that the system will be used with. So, you need to rebuild, using Access 2010, period. Try creating a new blank database (in 2010) and importing the objects one (or a few) at a time. Make sure the system is split. One file for the FE (forms, queries, reports, code, etc.) and one for the BE (tables only). Make sure that the Filter On Load property of all forms is set to No. If the recordsource for the form contains a where clause, make sure that the newly entered records meet the criteria for the where clause.
I am looking for a scripted/automated way (presumably VBA?) to take an Access query and generate some kind of savable, searchable, publish-able documentation on the data lineage. So if there were a bunch of layered/nested queries, or even passthrough queries, along the way I want a way to trace the final fields in the specified query back until I get back to the original source tables/fields.
Everything I've found seems to do database documentation focused on how the table relationships are configured. I'm looking for a way to get the documentation of the user-created portion, down to the field. I'm very open-minded on what format the output is in. I'm convinced this must be possible, but haven't had any luck yet.
I'm also open to recommendations for a third-party application if it could do this.
Thanks in advance!
Access does have a built in “dependency” feature. The result is a VERY nice tree-view of those dependencies, and you can even launch such objects using that treeview of your application to “navigate” the application so to speak.
The option is found under database tools and is appropriately called Object Dependencies.
The result looks like this:
While you don't want to use auto correct, this feature will force on track changes. If this is a large application, then on first run a significant delay will occur. After that, the results can be viewed instantly. As noted, not only do you have a hierarchical tree view, but objects in the tree view can be clicked on to launch the object in question.
And the above will work for a query that based on a query etc. all the way down to the base table.
https://www.dropbox.com/sh/f73rs3h9u9q2xk5/AAArloN_Cmf_WbPZ4W75I6KVa?dl=0
This is a set of queries I wrote to provide the kind of documentation you're looking for. It seems a bit kludgy, but it works for me. It's not a simple as the other response, but it provides output that can be incorporated into other documentation.
Note - the documentation is out of date with respect to Union queries. The query I have to analyze Union queries seems to only pick up the 1st two things that go into the Union, so I changed this to a Make Table query, and manually edit the resulting table to add the missing relationships.
To use the queries:
Copy the table and all the queries into your database
Run the "Mapping Unions Make Table" query
Manually edit the Unions table if necessary
When you run any of the 3 main output queries, you are prompted for the Top object you want to analyze. Enter the name of a query or table to find all the dependencies for that object. The three main outputs are:
Mapping Summary - lists all of the objects that go into the top object and all of the objects that go into them, to a depth of about 10 (depth is controlled in the "Mapping all parents" query)
Mapping summary without duplicates
Mapping summary duplicates
I especially like the 2nd output - this is in a format that can be saved in Excel and input to Visio's Org Chart Wizard to get a simple graphical representation of the relationships. Then the 3rd output query can be used to manually add in the queries that go into more than one other query, which Visio's wizard cannot handle.
I'm trying to work at getting the same information from a couple different sources but have hit a wall in trying to use NotesSQL and SQL 2008. What I am trying to do is to retrieve info from a couple different views on Domino servers. One view is a default view, the other is a created one.
One method I have used is Powershell, where I get the database, then select the view, get the first document & then iterate through the rest of the view grabbing fields that I need. The view I have selected is the People view.
I was trying to replicate this same thing using SQL 2008, using the NotesSQL driver, setting up an ODBC connection, and then creating a linked server to that Notes database. I am using the following query to select from the People view:
select * from openquery(MyNotesServer,'Select * from People')
However, what is returned from this view isn't what I am able to see when I use Powershell & then iterate through the documents returned in that view. Powershell shows 100+ columns in it, while SQL only returns 5 columns. Additionally, they're named "_12", "17" etc. Some fields (which may be custom, I don't know) have a meaningful name. Of the fields shown, I can select them by name ("_12", etc) but cannot select anything else. The number of rows (SQL) is the same as the number of documents in the view (Powershell $view.Allentries.Count).
Querying the view that was created (3 fields):
select * from openquery(MyNotesServer,'Select * from MyCreatedView')
returns all the fields in that view, and they are named as they are in the view.
In T-SQL querying the People view, how do you get the names of the columns that I know are there as I discovered in my Powershell script? They don't appear to be named the same thing, so how do you retrieve more than the 5 returned when you select * from the view? I have read through the Notes documentation & examples, but haven't been able to figure out what is mapped to where.
The reasoning behind this is wanting to utilize SQL & a notes.id file instead of running a script. Also, I want to make use of an already existing global view instead of views that may be accessible only to their author.
You can use select * from Person. Person is a form name, not a view name. Notes and Domino are not relational. The NSF file is a document database. The views in it are pre-built indexes that already have an implicit select. I.e., the "People" view selects all documents created with the "Person" form.
The above query bypasses the use of a view and will give you all the fields for all documents created with the the Person form.
Actually, come to think of it, the better query would be select * from Person where type='Person'. That's because the People view in Domino uses type="Person" instead of form="Person" in its selection formula. It is theoretically possible to have a document created with the Person form but with the Type field set to a different value. This variation will insure that you always get the same list that you see in the Person view.
But: In either case, it will be inefficient. The NotesSQL driver will have to do a full database search instead of simply reading the index of an existing view. It's going to search using the Notes formula SELECT Form="Person" & Type="Person". I really cannot recommend this, unless you are querying against a small Domino Directory database.
The best practice is to create a view containing all the fields that you really need, and do your query against that view.
First, in the Lotus Notes documentation, you'll find "columns" when you read about views, not fields.
Second, the columns have configured an option called "Programmatic Name". In that option, you can put an "alias". Lotus Notes puts values by default as "$12", "$17", etc. The thing is NotesSQL changes "$" by "_". That's the reason why you see "_12", "_17, etc.
How do you get the original names? As far as I remember (I don't have Lotus Notes near to make a verification) you can't. But, you can create another view with the columns with the data you need, and put appropiate names. The easy way to do it is copy/paste the view, delete the columns you don't need, and change that you want.
I'm using MS Access 2007 as a front end and have all linked tables in SQLServer 2008 R2 backend.
In a form in Access I am trying to execute the FIND button either in the ribbon or by creating a button on the form with the expressed purpose of looking for records with a specific value in a particular field.
When I complete the entry in the FIND window, I click on Find Next. In some cases, the record(s) is found immediately. In others, it can go for hours only to report that it can't find anything (when I know it should).
The table I am looking in has approximately 99,000 records in it. It doesn't seem to matter whether or not the field is indexed.
Is there something I'm doing wrong, or is Access unable to handle this? Also, is creating a stored procedure with handling multiple search requests and passing the info to Access the answer?
The find methods are known to be slow with ODBC data sources. Here is what the Access 2007 Recordset.FindFirst Method help topic says:
When working with Microsoft Access database engine-connected ODBC databases and large dynaset-type Recordset objects, you might discover that using the Find methods or using the Sort or Filter property is slow. To improve performance, use SQL queries with customized ORDER BY or WHERE clauses, parameter queries, or QueryDef objects that retrieve specific indexed records.
Futhermore, binding an Access form to a record source of 99K records is a performance challenge. Use a query as the form's record source, and design the query to return only one or a few rows.
Give the user an option to choose a different set of rows, and modify the form's record source property to reflect the user's choice.
This depends on the type of search you need and on the data type of the column (field) to be searched. For example, if I have a text data type in an indexed column and I search using Start of field or Whole field, it will be quite fast, however, if I search for Any part of field, it may well fall over. In other words, if Access can use an index for the search, it will work, even on quite a large table, otherwise, you may be best with a stored procedure, though I doubt that will be fast without an index, either.
What is the best way to re-use reports on different tables / datasets?
I have a number of reports built in BIRT, which get their data from a flat (un-normalized) MySQL table, the data which in turn has been imported from an excel sheet.
In BIRT, I've constructed my query like this, such that I can change the field names and re-use the report:
SELECT * FROM
(SELECT index as "Index", name as "Name", param1 as "First Parameter" FROM mytable) t
However, then when I switch to a new client's data, I need to change the query to the new data source and this doesn't seem sustainable or anywhere near a good practice.
So... what is a good practice?
Is this a reporting issue, or a database-design issue?
Do I create a standard view that the report connects to?
If I have a standard view, do I create a different view with the same structure for each data table, or keep replacing the view with a reference to the correct data table each time I run the report?
What's annoying is the excel sheets keep changing - new columns are added, and different clients name their data differently. Even if I can standardize this, I'd store different client data in different tables... so would I need to create a different report for each client, or pass in the table name to the report?
There are two ways and the path you choose is really dictated by how much flexibility you have architecturally.
First, you are on the right track by renaming your selected columns to a common name since that name is what is used to bind the data to the control on the report. Have you considered a stored procedure to access the data? This removes the query from the report and allows you to set up the stored proc on any database to return the necessary columns. If you cannot off-load to a stored proc, you can always rely on altering the query text at run-time. Because BIRT reports are not compiled (they are XML) you can change the query based on parameters and have it executed for each run of the design. Look at the onCreate event for the Data Set and you can access this.queryText and do any dynamic string substitution you need via JavaScript. Hidden parameters are a good way to help alter/tune the query. If you build the Data Set correctly, the changing of the underlying data could be as easy as changing the Data Source and then re-associating the Data Set to the new Data Source (in the edit data set window). I have done this MANY times and it works well. If you are going down this route, I would add the Data Source(s), Data Set(s) and any controls that they provide data to a report library. With the library you can use the controls in many reports and maintain them in one spot. If you update the library, all the reports using the library get updated as well.
Alternatively, if you want to really commit to a fully re-usable strategy that allows you to build a library of reusable components you could check out the free Reusable Component Library at BIRT Exchange (Reusable Component Library). In my opinion this strategy would give you the re-use you are looking for but at the expense of maintainability. It is abstraction to the point of obfuscation. It requires totally generic names for columns and controls that make debugging very difficult. While it would not be my first choice (the option above would be) others have used it successfully so I thought I would include it here since it directly speaks to your question.