Deploying to hundreds of mysql databases [duplicate] - mysql

Is there any way to easily create a stored procedure on multiple MySQL databases at once? All the databases are on the same MySQL install.

Installing in all schemas
To get a list of the schemas, use show databases;. Combine this with -- use:
use schemaA;
-- use schemaB;
-- use schemaC;
create procedure ...
Manually iterate through the schemas, removing and uncommenting use clauses as you move on, checking that everything works out. In MySQL Workbench, Ctrl+Shift+Enter is your friend.
Installing routines in a subset of schemas
Normally you don't want to install the stored routine in all schemas on a server, but only in a subset --- often defined by the set of schemas which already have some specific stored routine installed. Then, as discussed on SO, you can use a query like this to get the names of the relevant schemas:
SELECT ROUTINE_SCHEMA FROM `information_schema`.`ROUTINES` where specific_name = 'MyRoutine';
Verification
After deploying routines, to verify the existence of them, you can use a query like this:
SELECT distinct
r1.ROUTINE_SCHEMA,
case when r2.specific_name is not null then '' else '####' end as RoutineName1,
case when r3.specific_name is not null then '' else '####' end as RoutineName2,
case when r4.specific_name is not null then '' else '####' end as RoutineName3
FROM
`information_schema`.`ROUTINES` as r1
LEFT JOIN (select * from `information_schema`.`ROUTINES` where specific_name = 'RoutineName1') as r2 on r1.routine_schema = r2.routine_schema
LEFT JOIN (select * from `information_schema`.`ROUTINES` where specific_name = 'RoutineName2') as r3 on r1.routine_schema = r3.routine_schema
LEFT JOIN (select * from `information_schema`.`ROUTINES` where specific_name = 'RoutineName3') as r4 on r1.routine_schema = r4.routine_schema
where
r1.specific_name = 'FilteringRoutineName';
This query will check whether RoutineName1, RoutineName2 and RoutineName3 exist in the database schemas on your server which have the routine FilteringRoutineName. If a routine is missing, it will be marked with ####.
Of course, this only checks for routine existence. To verify their implementation, you may need a database diff tool (such as MySQL Compare or similar).

Assuming you are using Linux, a simple BASH loop with an array of schema names will let you do this.
Save your procedure definition to a file (e.g. myproc.sql), then use the file as input to mysql in the loop. If you put your sign-in details in ~/.my.cnf you can also avoid having to put usernames and passwords on the cmdline.
for i in dbname1 dbname2 dbname3; do mysql ${i} < myproc.sql; done;

I would recommend doing a copy-paste and create the stored procedure in each database schema if they need to be available to that schema only. Otherwise I would follow the recommendation from 'Kelly Vista' and just refer to the stored procedure located in one of the schema's.

Related

Attempt to fetch logical page in database 2 failed. It belongs to allocation unit X not to Y

Started to get following error when executing certain SP. Code related to this error is pretty simple, joining #temp table to real table
Full text of error:
Msg 605, Level 21, State 3, Procedure spSSRSRPTIncorrectRevenue, Line 123
Attempt to fetch logical page (1:558552) in database 2 failed. It belongs to allocation unit 2089673263876079616 not to 4179358581172469760.
Here is what I found:
https://support.microsoft.com/en-us/kb/2015739
This suggests some kind of issue with database. I run DBCC CHECKDB on user database and on temp database - all passes.
Second thing I'm doing - trying to find which table those allocation units belong
SELECT au.allocation_unit_id, OBJECT_NAME(p.object_id) AS table_name, fg.name AS filegroup_name,
au.type_desc AS allocation_type, au.data_pages, partition_number
FROM sys.allocation_units AS au
JOIN sys.partitions AS p ON au.container_id = p.partition_id
JOIN sys.filegroups AS fg ON fg.data_space_id = au.data_space_id
WHERE au.allocation_unit_id in(2089673263876079616, 4179358581172469760)
ORDER BY au.allocation_unit_id
This returns 2 objects in tempdb, not in user db. So, it makes me think it's some kind of data corruption in tempdb? I'm developer, not DBA. Any suggestions on what I should check next?
Also, when I run query above, how can I tell REAL object name that I understand? Like #myTempTable______... instead of #07C650CE
I was able to resolve this by clearing the SQL caches:
DBCC FREEPROCCACHE
GO
DBCC DROPCLEANBUFFERS
GO
Apparently restarting the SQL service would have had the same affect.
(via Made By SQL, reproduced here to help others!)
I have like your get errors too.
firstly you must backing up to table or object for dont panic more after. I tryed below steps on my Database.
step 1:
Backing up table (data movement to other table as manuel or vs..how can you do)
I used to below codes to my table move other table
--CODE-
set nocount on;
DECLARE #Counter INT = 1;
DECLARE #LastRecord INT = 10000000; --your table_count
WHILE #Counter < #LastRecord
BEGIN
BEGIN TRY
BEGIN
insert into your_table_new SELECT * FROM your_table WHERE your_column= #Counter --dont forget! create your_table_new before
END
END TRY
BEGIN CATCH
BEGIN
insert into error_code select #Counter,'error_number' --dont forget the create error_code table before.
END
END CATCH
SET #Counter += 1;
END;
step 2:
-DBCC CHECKTABLE(your_table , REPAIR_REBUILD )
GO
check your table. if you have an error go to other step_3.
step 3:
!!attention!! you can lost some data/datas on your table. but dont worry. so you backed-up your table in step_1.
-DBCC CHECKTABLE(your_table , REPAIR_ALLOW_DATA_LOSS)
GO
Good luck!
~~pektas
In my case, truncating and re-populating data in the concerned tables was the solution.
Most probably the data inside tables was corrupted.
Database ID 2 means your tempdb is corrupted. Fixing tempdp is easy. Restart sqlserver service and you are good to go.
This could be an instance of a bug Microsoft fixed on SQL Server 2008 with queries on temporary tables that self reference (for example we have experienced it when loading data from a real table to a temporary table while filtering any rows we already have populated in the temp table in a previous step).
It seems that it only happens on temporary tables with no identity/primary key, so a workaround is to add one, although if you patch CU3 or later you also can enable the hotfix via turning a trace flag on.
For more details on the bug/fixes: https://support.microsoft.com/en-us/help/960770/fix-you-receive-error-605-and-error-824-when-you-run-a-query-that-inse

Dynamic access to a server by server name

In SQL Server (i'm using 2008) is it possible to dynamically access server by server name?
My scenario: I have a production server, a development server, and a test server. Their structure is the same. There is a fourth server with some additional data - let's call it a data server.
On the data server there is a procedure. One of it's parameters is a name of the requesting server:
proc sp_myProcedure(#myId int, #serverName nvarchar(100))
The procedure accesses tables from the data server and from the requesting server. At the moment, to query the requesting server I'm using a case expression:
-- code on the data server
select additionalData = case #serverName
-- if the requesting server is production - query production
when 'ProdServer' then (select field1 from [ProdServer].[MyDataBase].[dbo].[MyTable] ...
-- if the requesting server is test - query test
when 'TestServer' then (select field1 from [TestServer].[MyDataBase].[dbo].[MyTable] ...
-- if the requesting server is development - query development
when 'DevServer' then (select field1 from [DevServer].[MyDataBase].[dbo].[MyTable] ...
end
My question is if there is any other way to access the requesting server. I'd like to replace ifs and cases with something more dynamic. Is it, for instance, possible to use the server name variable to dynamically access specific server. Something similar to the following (mocked) query:
declare myServer <server type> = Get_Server(#serverName)
-- the query
additionalData = select field1 from [myServer].[MyDataBase].[dbo].[MyTable]
I liked this approach
SELECT
SERVERPROPERTY('MachineName') AS [ServerName],
SERVERPROPERTY('ServerName') AS [ServerInstanceName],
SERVERPROPERTY('InstanceName') AS [Instance],
SERVERPROPERTY('Edition') AS [Edition],
SERVERPROPERTY('ProductVersion') AS [ProductVersion],
Left(##Version, Charindex('-', ##version) - 2) As VersionName
Link
Another approach which we were using was
Creating one database called database_yourprojectname
So, for the explanation I'm using database name as northwind
after that you can create one new database called northwind_db
Which has a following fields:
Servername,username(encrypted),password(encrypted),active
And then you can either make one page to insert/update/delete current database used there
or you can add statically data to it..so, you can use the database which is active currently.
Or use simple one:
SELECT ##SERVERNAME
Which is already stated here

Find recent object changes in SQL Server Database

I've added and modified several (new and existing resp.) tables and stored procs, for a particular database and server, in last 3 months.
I was thinking if there's any SQL query by which I can determine all those changes.
Thanks.
Query the sys.objects table to find the objects that changed and filter by modify_date and type; U = User table, P = Stored procedure.
select *
from sys.objects
where (type = 'U' or type = 'P')
and modify_date > dateadd(m, -3, getdate())
This approach will tell you what objects have changed, but not the specific changes.
Hi you can get the changed/modified db object details with this query
select name,create_date,modify_date
from sys.procedures
order by modify_date desc
Thanks
I don't think you're going to be able to find what you're looking for. SQL Server just doesn't track that information out of the box.
To handle this in the future, you can use some kind of source control (redgate, for one: http://www.red-gate.com/products/sql-development/sql-source-control),
or you can set up a DDL trigger (one such technique is described here: https://dba.stackexchange.com/questions/33541/how-to-keep-history-of-sql-server-stored-procedure-revisions/33544#33544).

List of aggregate functions

Is there a way to fetch list of aggregate functions supported by a dbms using jdbc metadata or running any dbms specific query?
On SQL Server you can query XML which is in installation directory:
DECLARE #xml XML
SELECT #xml = x.y
FROM OPENROWSET( BULK 'C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\SqlToolsData\1033\SQLCommonObjects.xml', SINGLE_BLOB ) x(y)
;WITH XMLNAMESPACES( 'http://tempuri.org/SqlCommonObjects.xsd' AS ns )
SELECT
Category.Name.value('ns:DisplayName[1]', 'VARCHAR(MAX)') [Category],
[Function].Name.value('ns:Name[1]', 'VARCHAR(MAX)') [Function],
[Function].Name.query('for $p in ns:Parameters/ns:Parameter return
concat($p/ns:Name[1],",")').value('.', 'VARCHAR(MAX)') Parameters
FROM #xml.nodes('//ns:Category[ns:DisplayName="Aggregate Functions"]')
AS Category(Name)
CROSS APPLY Category.Name.nodes('ns:Objects/ns:Function') [Function](Name)
Where after BULK statement you should give your folder(difference mainly is Program Files" and "Program_Files(x86)" and SQL server version (100 is 2008 in example)
Your post has multiple DB tags, and each has system catalogs and/or an information schema that would let you know the list of procedures. Which table/view to query will differ from a DB engine to the next, however... (For instance, in Postgres you'd join pg_proc and pg_aggregate, since information_schema.routines won't tell you which procs are aggregates.)
It is usually safe to assume that typical aggregate functions (sum(), count(), avg()...) exist in all database implementations.
The only exception I'm aware of is Postgres, which does not support any()/some() due to ambiguity in the syntax:
SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...;
There is nothing fullproof, since it is not part of the JDBC spec. If you don't know what database engine you are using at runtime, your best bet is to submit a test query to the database and check whether or not it failed before using any aggregate function that may not be supported.

Install Stored Procedure on Multiple Databases

Is there any way to easily create a stored procedure on multiple MySQL databases at once? All the databases are on the same MySQL install.
Installing in all schemas
To get a list of the schemas, use show databases;. Combine this with -- use:
use schemaA;
-- use schemaB;
-- use schemaC;
create procedure ...
Manually iterate through the schemas, removing and uncommenting use clauses as you move on, checking that everything works out. In MySQL Workbench, Ctrl+Shift+Enter is your friend.
Installing routines in a subset of schemas
Normally you don't want to install the stored routine in all schemas on a server, but only in a subset --- often defined by the set of schemas which already have some specific stored routine installed. Then, as discussed on SO, you can use a query like this to get the names of the relevant schemas:
SELECT ROUTINE_SCHEMA FROM `information_schema`.`ROUTINES` where specific_name = 'MyRoutine';
Verification
After deploying routines, to verify the existence of them, you can use a query like this:
SELECT distinct
r1.ROUTINE_SCHEMA,
case when r2.specific_name is not null then '' else '####' end as RoutineName1,
case when r3.specific_name is not null then '' else '####' end as RoutineName2,
case when r4.specific_name is not null then '' else '####' end as RoutineName3
FROM
`information_schema`.`ROUTINES` as r1
LEFT JOIN (select * from `information_schema`.`ROUTINES` where specific_name = 'RoutineName1') as r2 on r1.routine_schema = r2.routine_schema
LEFT JOIN (select * from `information_schema`.`ROUTINES` where specific_name = 'RoutineName2') as r3 on r1.routine_schema = r3.routine_schema
LEFT JOIN (select * from `information_schema`.`ROUTINES` where specific_name = 'RoutineName3') as r4 on r1.routine_schema = r4.routine_schema
where
r1.specific_name = 'FilteringRoutineName';
This query will check whether RoutineName1, RoutineName2 and RoutineName3 exist in the database schemas on your server which have the routine FilteringRoutineName. If a routine is missing, it will be marked with ####.
Of course, this only checks for routine existence. To verify their implementation, you may need a database diff tool (such as MySQL Compare or similar).
Assuming you are using Linux, a simple BASH loop with an array of schema names will let you do this.
Save your procedure definition to a file (e.g. myproc.sql), then use the file as input to mysql in the loop. If you put your sign-in details in ~/.my.cnf you can also avoid having to put usernames and passwords on the cmdline.
for i in dbname1 dbname2 dbname3; do mysql ${i} < myproc.sql; done;
I would recommend doing a copy-paste and create the stored procedure in each database schema if they need to be available to that schema only. Otherwise I would follow the recommendation from 'Kelly Vista' and just refer to the stored procedure located in one of the schema's.